From b848dec86a6abe467b13dc2148cbbb6da7fba096 Mon Sep 17 00:00:00 2001 From: rusdevops Date: Thu, 12 Oct 2017 07:53:24 -0700 Subject: [PATCH 01/27] Update CMakeLists.txt --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18f5f7ac..a17532ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,7 @@ SET(CMAKE_INSTALL_LIBDIR lib CACHE PATH "Output directory for libraries") IF(VMIME_BUILD_SHARED_LIBRARY) INSTALL( TARGETS ${VMIME_LIBRARY_NAME} + EXPORT ${VMIME_LIBRARY_NAME}-config LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs ) @@ -207,6 +208,7 @@ ENDIF() IF(VMIME_BUILD_STATIC_LIBRARY) INSTALL( TARGETS ${VMIME_LIBRARY_NAME}-static + EXPORT ${VMIME_LIBRARY_NAME}-config LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs ) @@ -222,6 +224,8 @@ INSTALL_HEADERS_WITH_DIRECTORY(VMIME_LIBRARY_GENERATED_INCLUDE_FILES headers "${ # COMPONENT headers #) +install(EXPORT ${VMIME_LIBRARY_NAME}-config DESTINATION cmake) + ############################################################################## # Tests From 51af739f8ecea4cde3f7ac2648be9c4c9ee421b4 Mon Sep 17 00:00:00 2001 From: rusdevops Date: Thu, 12 Oct 2017 08:06:53 -0700 Subject: [PATCH 02/27] Update CMakeLists.txt --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a17532ba..74291351 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,10 @@ IF(VMIME_BUILD_SHARED_LIBRARY) ${VMIME_LIBRARY_INCLUDE_FILES} ) + TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME} PUBLIC + $ + ) + GENERATE_EXPORT_HEADER( ${VMIME_LIBRARY_NAME} BASE_NAME VMIME @@ -154,6 +158,10 @@ IF(VMIME_BUILD_STATIC_LIBRARY) ${VMIME_LIBRARY_INCLUDE_FILES} ) + TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME}-static PUBLIC + $ + ) + GENERATE_EXPORT_HEADER( ${VMIME_LIBRARY_NAME}-static BASE_NAME VMIME From dff676572a9f04649cd789c0b9fdb21aab190c30 Mon Sep 17 00:00:00 2001 From: Jan Osusky Date: Fri, 20 Oct 2017 14:05:01 +0200 Subject: [PATCH 03/27] Add SMTPS with AUTH PLAIN without SASL GNU SASL is a nice library but comes with its own prerequisites and dependencies. As IMAP and POP3 are able to work without SASL it seems to me logical to add some authentication support to SMTP too. As these days most of the communication is encrypted it is common to use simple mechanism like AUTH PLAIN, so I have added it. --- src/vmime/net/smtp/SMTPConnection.cpp | 38 ++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/vmime/net/smtp/SMTPConnection.cpp b/src/vmime/net/smtp/SMTPConnection.cpp index 3785126a..8709efe4 100644 --- a/src/vmime/net/smtp/SMTPConnection.cpp +++ b/src/vmime/net/smtp/SMTPConnection.cpp @@ -40,6 +40,10 @@ #if VMIME_HAVE_SASL_SUPPORT #include "vmime/security/sasl/SASLContext.hpp" +#else + #include "vmime/utility/encoder/b64Encoder.hpp" + #include "vmime/utility/inputStreamStringAdapter.hpp" + #include "vmime/utility/outputStreamStringAdapter.hpp" #endif // VMIME_HAVE_SASL_SUPPORT #if VMIME_HAVE_TLS_SUPPORT @@ -48,7 +52,6 @@ #endif // VMIME_HAVE_TLS_SUPPORT - // Helpers for service properties #define GET_PROPERTY(type, prop) \ (m_transport.lock()->getInfos().getPropertyValue (getSession(), \ @@ -307,6 +310,39 @@ void SMTPConnection::authenticate() throw; } } +#else // no SASL + + // allow AUTH PLAIN over TLS - it is a popular and simple mechanism + if (m_secured) + { + std::vector authMechs; + hasExtension("AUTH", &authMechs); + + if (authMechs.empty()) + throw exceptions::authentication_error("No AUTH mechanism available."); + + const string plain("PLAIN"); + if (std::find(authMechs.begin(), authMechs.end(), plain) != authMechs.end()) + { + const string username = getAuthenticator()->getUsername(); + const string password = getAuthenticator()->getPassword(); + const string authToken = username + '\0' + username + '\0' + password; + auto encoder = new vmime::utility::encoder::b64Encoder(); + utility::inputStreamStringAdapter in(authToken); + string authTokenBase64; + utility::outputStreamStringAdapter out(authTokenBase64); + encoder->encode(in, out); + sendRequest(SMTPCommand::AUTH(plain, authTokenBase64)); + shared_ptr response = readResponse(); + const int code = response ? response->getCode() : -1; + if (code == 235) + { + m_authenticated = true; + return; + } + } + } + #endif // VMIME_HAVE_SASL_SUPPORT // No other authentication method is possible From 1592cccb6102ba3c28dbcb2387741c692164631e Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 14 Dec 2017 21:39:29 +0100 Subject: [PATCH 04/27] Fixed #186: use SMTPUTF8 only when needed. --- src/vmime/net/smtp/SMTPCommand.cpp | 3 + src/vmime/net/smtp/SMTPTransport.cpp | 34 +++- src/vmime/net/smtp/SMTPTransport.hpp | 2 + tests/net/smtp/SMTPTransportTest.cpp | 72 +++++++++ tests/net/smtp/SMTPTransportTestUtils.hpp | 182 ++++++++++++++++++++++ tests/testUtils.cpp | 14 ++ 6 files changed, 304 insertions(+), 3 deletions(-) diff --git a/src/vmime/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index 27c8ec1b..04c78722 100644 --- a/src/vmime/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp @@ -153,6 +153,9 @@ shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8) cmd << ">"; + if (utf8) + cmd << " SMTPUTF8"; + return createCommand(cmd.str()); } diff --git a/src/vmime/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index 2af6a195..fb9ea9aa 100644 --- a/src/vmime/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp @@ -152,6 +152,22 @@ void SMTPTransport::noop() } +// static +bool SMTPTransport::mailboxNeedsUTF8(const mailbox& mb) +{ + bool all7bit = + utility::stringUtils::is7bit(mb.getEmail().getLocalName().getBuffer()) + && utility::stringUtils::is7bit(mb.getEmail().getDomainName().getBuffer()); + + for (size_t i = 0, n = mb.getName().getWordCount() ; all7bit && i != n ; ++i) + { + all7bit = utility::stringUtils::is7bit(mb.getName().getWordAt(i)->getBuffer()); + } + + return !all7bit; +} + + void SMTPTransport::sendEnvelope (const mailbox& expeditor, const mailboxList& recipients, const mailbox& sender, bool sendDATACommand, @@ -181,9 +197,21 @@ void SMTPTransport::sendEnvelope const bool hasSize = m_connection->hasExtension("SIZE"); if (!sender.isEmpty()) - commands->addCommand(SMTPCommand::MAIL(sender, hasSMTPUTF8, hasSize ? size : 0)); + { + commands->addCommand( + SMTPCommand::MAIL( + sender, hasSMTPUTF8 && mailboxNeedsUTF8(sender), hasSize ? size : 0 + ) + ); + } else - commands->addCommand(SMTPCommand::MAIL(expeditor, hasSMTPUTF8, hasSize ? size : 0)); + { + commands->addCommand( + SMTPCommand::MAIL( + expeditor, hasSMTPUTF8 && mailboxNeedsUTF8(expeditor), hasSize ? size : 0 + ) + ); + } // Now, we will need to reset next time m_needReset = true; @@ -192,7 +220,7 @@ void SMTPTransport::sendEnvelope for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { const mailbox& mbox = *recipients.getMailboxAt(i); - commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8)); + commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && mailboxNeedsUTF8(mbox))); } // Prepare sending of message data diff --git a/src/vmime/net/smtp/SMTPTransport.hpp b/src/vmime/net/smtp/SMTPTransport.hpp index a0f02418..7b266d3d 100644 --- a/src/vmime/net/smtp/SMTPTransport.hpp +++ b/src/vmime/net/smtp/SMTPTransport.hpp @@ -91,6 +91,8 @@ public: private: + static bool mailboxNeedsUTF8(const mailbox& mb); + /** Send the MAIL and RCPT commands to the server, checking the * response, and using pipelining if supported by the server. * Optionally, the DATA command can also be sent. diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp index dd5546cc..d1a31a5a 100644 --- a/tests/net/smtp/SMTPTransportTest.cpp +++ b/tests/net/smtp/SMTPTransportTest.cpp @@ -39,6 +39,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST(testChunking) VMIME_TEST(testSize_Chunking) VMIME_TEST(testSize_NoChunking) + VMIME_TEST(testSMTPUTF8_available) + VMIME_TEST(testSMTPUTF8_notAvailable) VMIME_TEST_LIST_END @@ -168,5 +170,75 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) vmime::net::smtp::SMTPMessageSizeExceedsMaxLimitsException); } + void testSMTPUTF8_available() + { + vmime::shared_ptr session = vmime::net::session::create(); + + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); + + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); + + VASSERT_NO_THROW("Connection", tr->connect()); + + vmime::mailbox exp( + vmime::emailAddress( + vmime::word("expéditeur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + ); + + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); + + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); + + tr->send(exp, recips, is, 0); + } + + void testSMTPUTF8_notAvailable() + { + vmime::shared_ptr session = vmime::net::session::create(); + + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); + + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); + + VASSERT_NO_THROW("Connection", tr->connect()); + + vmime::mailbox exp( + vmime::emailAddress( + vmime::word("expéditeur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + ); + + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); + + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); + + tr->send(exp, recips, is, 0); + } + VMIME_TEST_SUITE_END diff --git a/tests/net/smtp/SMTPTransportTestUtils.hpp b/tests/net/smtp/SMTPTransportTestUtils.hpp index c1224216..cfd830cf 100644 --- a/tests/net/smtp/SMTPTransportTestUtils.hpp +++ b/tests/net/smtp/SMTPTransportTestUtils.hpp @@ -591,3 +591,185 @@ public: }; typedef SMTPBigTestMessage <4194304> SMTPBigTestMessage4MB; + + + +/** SMTP test server for SMTPUTF8 extension. + */ +template +class UTF8SMTPTestSocket : public lineBasedTestSocket +{ +public: + + UTF8SMTPTestSocket() + { + if (SUPPORTS_UTF8) + { + m_rcptLines.insert("RCPT TO:"); + m_rcptLines.insert("RCPT TO:"); + m_rcptLines.insert("RCPT TO: SMTPUTF8"); + } + else + { + m_rcptLines.insert("RCPT TO:"); + m_rcptLines.insert("RCPT TO:"); + m_rcptLines.insert("RCPT TO:<=?utf-8?Q?r=C3=A9cepteur?=@test.vmime.org>"); + } + + m_state = STATE_NOT_CONNECTED; + m_ehloSent = m_mailSent = m_rcptSent = m_dataSent = m_quitSent = false; + } + + ~UTF8SMTPTestSocket() + { + } + + void onConnected() + { + localSend("220 test.vmime.org Service ready\r\n"); + processCommand(); + + m_state = STATE_COMMAND; + } + + void processCommand() + { + if (!haveMoreLines()) + return; + + vmime::string line = getNextLine(); + std::istringstream iss(line); + + switch (m_state) + { + case STATE_NOT_CONNECTED: + + localSend("451 Requested action aborted: invalid state\r\n"); + break; + + case STATE_COMMAND: + { + std::string cmd; + iss >> cmd; + + if (cmd.empty()) + { + localSend("500 Syntax error, command unrecognized\r\n"); + } + else if (cmd == "EHLO") + { + if (SUPPORTS_UTF8) + { + localSend("250-test.vmime.org\r\n"); + localSend("250 SMTPUTF8\r\n"); + } + else + { + localSend("250 test.vmime.org\r\n"); + } + + m_ehloSent = true; + } + else if (cmd == "HELO") + { + VASSERT("Client must not send the HELO command, as EHLO succeeded", false); + } + else if (cmd == "MAIL") + { + VASSERT("Client must send the EHLO command", m_ehloSent); + VASSERT("The MAIL command must be sent only one time", !m_mailSent); + + if (SUPPORTS_UTF8) + { + VASSERT_EQ("MAIL", std::string("MAIL FROM: SMTPUTF8"), line); + } + else + { + VASSERT_EQ("MAIL", std::string("MAIL FROM:<=?utf-8?Q?exp=C3=A9diteur?=@test.vmime.org>"), line); + } + + localSend("250 OK\r\n"); + + m_mailSent = true; + } + else if (cmd == "RCPT") + { + std::set ::iterator it = m_rcptLines.find(line); + + VASSERT(std::string("RCPT not found: '") + line + "'", it != m_rcptLines.end()); + + m_rcptLines.erase(it); + + localSend("250 OK, recipient accepted\r\n"); + + m_rcptSent = true; + } + else if (cmd == "DATA") + { + VASSERT("Client must send the MAIL command", m_mailSent); + VASSERT("Client must send the RCPT command", m_rcptSent); + VASSERT("All recipients", m_rcptLines.empty()); + + localSend("354 Ready to accept data; end with .\r\n"); + + m_state = STATE_DATA; + m_msgData.clear(); + + m_dataSent = true; + } + else if (cmd == "NOOP") + { + localSend("250 Completed\r\n"); + } + else if (cmd == "QUIT") + { + m_quitSent = true; + + localSend("221 test.vmime.org Service closing transmission channel\r\n"); + } + else + { + localSend("502 Command not implemented\r\n"); + } + + break; + } + case STATE_DATA: + { + if (line == ".") + { + VASSERT_EQ("Data", "Message data\r\n", m_msgData); + + localSend("250 Message accepted for delivery\r\n"); + m_state = STATE_COMMAND; + } + else + { + m_msgData += line + "\r\n"; + } + + break; + } + + } + + processCommand(); + } + +private: + + enum State + { + STATE_NOT_CONNECTED, + STATE_COMMAND, + STATE_DATA + }; + + int m_state; + + std::set m_rcptLines; + + std::string m_msgData; + + bool m_ehloSent, m_mailSent, m_rcptSent, m_dataSent, m_quitSent; +}; diff --git a/tests/testUtils.cpp b/tests/testUtils.cpp index 0eb2bfd4..1e8e0c99 100644 --- a/tests/testUtils.cpp +++ b/tests/testUtils.cpp @@ -26,6 +26,11 @@ #include "vmime/utility/stringUtils.hpp" #include +#include + + +// Enable to output socket send/receive on standard output +#define DEBUG_SOCKET_IN_OUT 0 @@ -156,6 +161,11 @@ vmime::size_t testSocket::sendRawNonBlocking(const vmime::byte_t* buffer, const void testSocket::localSend(const vmime::string& buffer) { m_inBuffer += buffer; + +#if DEBUG_SOCKET_IN_OUT + std::cout << "> " << vmime::utility::stringUtils::trim(buffer) << std::endl; +#endif // DEBUG_SOCKET_IN_OUT + } @@ -232,6 +242,10 @@ void lineBasedTestSocket::onDataReceived() if (!line.empty() && line[line.length() - 1] == '\r') line.erase(line.end() - 1, line.end()); +#if DEBUG_SOCKET_IN_OUT + std::cout << "< " << vmime::utility::stringUtils::trim(line) << std::endl; +#endif // DEBUG_SOCKET_IN_OUT + m_lines.push_back(line); m_buffer.erase(m_buffer.begin(), m_buffer.begin() + eol + 1); } From d7a1b5817e8389e9a4ea3d33c4dd250df9c6860c Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 14 Dec 2017 22:11:58 +0100 Subject: [PATCH 05/27] Issue #186: SMTPUTF8 is not an argument to RCPT + UTF8 in recipient address must switch the whole message to SMTPUTF8. --- src/vmime/net/smtp/SMTPCommand.cpp | 3 - src/vmime/net/smtp/SMTPTransport.cpp | 22 ++- tests/net/smtp/SMTPTransportTest.cpp | 164 +++++++++++++++------- tests/net/smtp/SMTPTransportTestUtils.hpp | 14 +- 4 files changed, 145 insertions(+), 58 deletions(-) diff --git a/src/vmime/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index 04c78722..27c8ec1b 100644 --- a/src/vmime/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp @@ -153,9 +153,6 @@ shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8) cmd << ">"; - if (utf8) - cmd << " SMTPUTF8"; - return createCommand(cmd.str()); } diff --git a/src/vmime/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index fb9ea9aa..25eb72a7 100644 --- a/src/vmime/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp @@ -192,15 +192,29 @@ void SMTPTransport::sendEnvelope if (needReset) commands->addCommand(SMTPCommand::RSET()); - // Emit the "MAIL" command + // Check whether we need SMTPUTF8 const bool hasSMTPUTF8 = m_connection->hasExtension("SMTPUTF8"); + bool needSMTPUTF8 = false; + + if (!sender.isEmpty()) + needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(sender); + else + needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(expeditor); + + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) + { + const mailbox& mbox = *recipients.getMailboxAt(i); + needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(mbox); + } + + // Emit the "MAIL" command const bool hasSize = m_connection->hasExtension("SIZE"); if (!sender.isEmpty()) { commands->addCommand( SMTPCommand::MAIL( - sender, hasSMTPUTF8 && mailboxNeedsUTF8(sender), hasSize ? size : 0 + sender, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0 ) ); } @@ -208,7 +222,7 @@ void SMTPTransport::sendEnvelope { commands->addCommand( SMTPCommand::MAIL( - expeditor, hasSMTPUTF8 && mailboxNeedsUTF8(expeditor), hasSize ? size : 0 + expeditor, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0 ) ); } @@ -220,7 +234,7 @@ void SMTPTransport::sendEnvelope for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { const mailbox& mbox = *recipients.getMailboxAt(i); - commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && mailboxNeedsUTF8(mbox))); + commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && needSMTPUTF8)); } // Prepare sending of message data diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp index d1a31a5a..cbfab4f5 100644 --- a/tests/net/smtp/SMTPTransportTest.cpp +++ b/tests/net/smtp/SMTPTransportTest.cpp @@ -33,12 +33,14 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST_LIST_BEGIN +/* VMIME_TEST(testConnectToInvalidServer) VMIME_TEST(testGreetingError) VMIME_TEST(testMAILandRCPT) VMIME_TEST(testChunking) VMIME_TEST(testSize_Chunking) VMIME_TEST(testSize_NoChunking) +*/ VMIME_TEST(testSMTPUTF8_available) VMIME_TEST(testSMTPUTF8_notAvailable) VMIME_TEST_LIST_END @@ -172,72 +174,138 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) void testSMTPUTF8_available() { - vmime::shared_ptr session = vmime::net::session::create(); + // Test with UTF8 sender + { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); - tr->setSocketFactory(vmime::make_shared > >()); - tr->setTimeoutHandlerFactory(vmime::make_shared ()); + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); - VASSERT_NO_THROW("Connection", tr->connect()); + VASSERT_NO_THROW("Connection", tr->connect()); - vmime::mailbox exp( - vmime::emailAddress( - vmime::word("expéditeur", vmime::charsets::UTF_8), - vmime::word("test.vmime.org") - ) - ); + vmime::mailbox exp( + vmime::emailAddress( + vmime::word("expéditeur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + ); - vmime::mailboxList recips; - recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); - recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); - recips.appendMailbox(vmime::make_shared ( - vmime::emailAddress( - vmime::word("récepteur", vmime::charsets::UTF_8), - vmime::word("test.vmime.org") - ) - )); + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); - vmime::string data("Message data"); - vmime::utility::inputStreamStringAdapter is(data); + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); - tr->send(exp, recips, is, 0); + tr->send(exp, recips, is, 0); + } + + // Test with UTF8 recipient only + { + vmime::shared_ptr session = vmime::net::session::create(); + + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); + + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); + + VASSERT_NO_THROW("Connection", tr->connect()); + + vmime::mailbox exp("expediteur@test.vmime.org"); + + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); + + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); + + tr->send(exp, recips, is, 0); + } } void testSMTPUTF8_notAvailable() { - vmime::shared_ptr session = vmime::net::session::create(); + // Test with UTF8 sender + { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); - tr->setSocketFactory(vmime::make_shared > >()); - tr->setTimeoutHandlerFactory(vmime::make_shared ()); + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); - VASSERT_NO_THROW("Connection", tr->connect()); + VASSERT_NO_THROW("Connection", tr->connect()); - vmime::mailbox exp( - vmime::emailAddress( - vmime::word("expéditeur", vmime::charsets::UTF_8), - vmime::word("test.vmime.org") - ) - ); + vmime::mailbox exp( + vmime::emailAddress( + vmime::word("expéditeur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + ); - vmime::mailboxList recips; - recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); - recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); - recips.appendMailbox(vmime::make_shared ( - vmime::emailAddress( - vmime::word("récepteur", vmime::charsets::UTF_8), - vmime::word("test.vmime.org") - ) - )); + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); - vmime::string data("Message data"); - vmime::utility::inputStreamStringAdapter is(data); + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); - tr->send(exp, recips, is, 0); + tr->send(exp, recips, is, 0); + } + + // Test with UTF8 recipient only + { + vmime::shared_ptr session = vmime::net::session::create(); + + vmime::shared_ptr tr = session->getTransport + (vmime::utility::url("smtp://localhost")); + + tr->setSocketFactory(vmime::make_shared > >()); + tr->setTimeoutHandlerFactory(vmime::make_shared ()); + + VASSERT_NO_THROW("Connection", tr->connect()); + + vmime::mailbox exp("expediteur@test.vmime.org"); + + vmime::mailboxList recips; + recips.appendMailbox(vmime::make_shared ("recipient1@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ("recipient2@test.vmime.org")); + recips.appendMailbox(vmime::make_shared ( + vmime::emailAddress( + vmime::word("récepteur", vmime::charsets::UTF_8), + vmime::word("test.vmime.org") + ) + )); + + vmime::string data("Message data"); + vmime::utility::inputStreamStringAdapter is(data); + + tr->send(exp, recips, is, 0); + } } VMIME_TEST_SUITE_END diff --git a/tests/net/smtp/SMTPTransportTestUtils.hpp b/tests/net/smtp/SMTPTransportTestUtils.hpp index cfd830cf..b5af2f10 100644 --- a/tests/net/smtp/SMTPTransportTestUtils.hpp +++ b/tests/net/smtp/SMTPTransportTestUtils.hpp @@ -607,7 +607,7 @@ public: { m_rcptLines.insert("RCPT TO:"); m_rcptLines.insert("RCPT TO:"); - m_rcptLines.insert("RCPT TO: SMTPUTF8"); + m_rcptLines.insert("RCPT TO:"); } else { @@ -681,11 +681,19 @@ public: if (SUPPORTS_UTF8) { - VASSERT_EQ("MAIL", std::string("MAIL FROM: SMTPUTF8"), line); + VASSERT( + "MAIL", + std::string("MAIL FROM: SMTPUTF8") == line + || std::string("MAIL FROM: SMTPUTF8") == line + ); } else { - VASSERT_EQ("MAIL", std::string("MAIL FROM:<=?utf-8?Q?exp=C3=A9diteur?=@test.vmime.org>"), line); + VASSERT( + "MAIL", + std::string("MAIL FROM:") == line + || std::string("MAIL FROM:<=?utf-8?Q?exp=C3=A9diteur?=@test.vmime.org>") == line + ); } localSend("250 OK\r\n"); From b73d765f51f60475ddc2a8c1fca428a78a57d489 Mon Sep 17 00:00:00 2001 From: Bo Simonsen Date: Mon, 19 Feb 2018 13:08:09 +0100 Subject: [PATCH 06/27] Handle parsing of a@b.c The behavior of current VMIME implementation will result in address a@b.c with an empty name. That is because the parsing is stopped whenever a wihtespace and a at-character is seen. We should continue the parsing to deduce the real address (e@f.g in the example). --- src/vmime/mailbox.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/vmime/mailbox.cpp b/src/vmime/mailbox.cpp index 7c6d5e3b..c4b230c4 100644 --- a/src/vmime/mailbox.cpp +++ b/src/vmime/mailbox.cpp @@ -234,8 +234,6 @@ void mailbox::parseImpl ++p; } - - break; } else { @@ -245,10 +243,6 @@ void mailbox::parseImpl } else if (state == State_Address) { - // Skip '<' character - if (*p == '<') - ++p; - bool escaped = false; int comment = 0; From abba40e97dabcd56f30f86add8917a7785710d41 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Mon, 12 Mar 2018 20:33:27 +0100 Subject: [PATCH 07/27] Added unit test related to PR #192. --- tests/parser/mailboxTest.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp index 6bf6670c..92fcd98f 100644 --- a/tests/parser/mailboxTest.cpp +++ b/tests/parser/mailboxTest.cpp @@ -30,6 +30,7 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) VMIME_TEST(testParse) VMIME_TEST(testEmptyEmailAddress) VMIME_TEST(testSeparatorInComment) + VMIME_TEST(testAddressInName) VMIME_TEST_LIST_END @@ -145,5 +146,14 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) VASSERT_EQ("email2", "bbb@vmime.org", mbox2->getEmail()); } + void testAddressInName() + { + vmime::mailbox mbox; + mbox.parse("a@b.c "); + + VASSERT_EQ("name", vmime::text("a@b.c"), mbox.getName()); + VASSERT_EQ("email", "e@f.g", mbox.getEmail()); + } + VMIME_TEST_SUITE_END From f04190bafa2ac2142856bb79cb7643ae9e13a58a Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Mon, 12 Mar 2018 20:37:12 +0100 Subject: [PATCH 08/27] #191 X509Certificate::import() now auto-detects format --- doc/book/net.tex | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/doc/book/net.tex b/doc/book/net.tex index 1e5f1803..ac3b70c3 100644 --- a/doc/book/net.tex +++ b/doc/book/net.tex @@ -931,17 +931,7 @@ vmime::shared_ptr vmime::utility::inputStreamAdapter is(certFile); vmime::shared_ptr cert; - // Try DER format - cert = vmime::security::cert::X509Certificate::import - (is, vmime::security::cert::X509Certificate::FORMAT_DER); - - if (cert != NULL) - return cert; - - // Try PEM format - is.reset(); - cert = vmime::security::cert::X509Certificate::import - (is, vmime::security::cert::X509Certificate::FORMAT_PEM); + cert = vmime::security::cert::X509Certificate::import(is); return cert; } From 8564b2f8b0d563a2c328a09916e9e4e3def5978f Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Sun, 1 Apr 2018 11:29:07 +0200 Subject: [PATCH 09/27] #193 Dropped support for boot::shared_ptr<>, enabled C++11 support in CMake --- CMakeLists.txt | 90 +---------- cmake/cmake-cxx11/.gitignore | 1 - cmake/cmake-cxx11/MERGE-TODO | 7 - .../Modules/CheckCXX11Features.cmake | 142 ------------------ .../cxx11-test-__func__.cpp | 8 - .../CheckCXX11Features/cxx11-test-auto.cpp | 12 -- .../cxx11-test-auto_fail_compile.cpp | 7 - .../cxx11-test-auto_ret_type.cpp | 8 - .../cxx11-test-class_override_final.cpp | 21 --- ...test-class_override_final_fail_compile.cpp | 25 --- .../cxx11-test-constexpr.cpp | 19 --- .../CheckCXX11Features/cxx11-test-cstdint.cpp | 11 -- .../cxx11-test-decltype.cpp | 10 -- .../cxx11-test-initializer_list.cpp | 27 ---- .../CheckCXX11Features/cxx11-test-lambda.cpp | 5 - .../cxx11-test-long_long.cpp | 7 - .../CheckCXX11Features/cxx11-test-nullptr.cpp | 6 - .../cxx11-test-nullptr_fail_compile.cpp | 6 - .../CheckCXX11Features/cxx11-test-regex.cpp | 26 ---- .../cxx11-test-rvalue-references.cpp | 57 ------- .../cxx11-test-sizeof_member.cpp | 14 -- .../cxx11-test-sizeof_member_fail.cpp | 9 -- .../cxx11-test-static_assert.cpp | 5 - .../cxx11-test-static_assert_fail_compile.cpp | 5 - .../cxx11-test-variadic_templates.cpp | 23 --- .../Tests/Module/CXX11Features/CMakeLists.txt | 33 ---- .../Module/CXX11Features/cxx11features.cxx | 57 ------- doc/book/building.tex | 2 - src/vmime/types.hpp | 50 +----- 29 files changed, 14 insertions(+), 679 deletions(-) delete mode 100644 cmake/cmake-cxx11/.gitignore delete mode 100644 cmake/cmake-cxx11/MERGE-TODO delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-__func__.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_fail_compile.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_ret_type.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final_fail_compile.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-constexpr.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-cstdint.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-decltype.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-initializer_list.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-lambda.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-long_long.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr_fail_compile.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-regex.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-rvalue-references.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member_fail.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert_fail_compile.cpp delete mode 100644 cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-variadic_templates.cpp delete mode 100644 cmake/cmake-cxx11/Tests/Module/CXX11Features/CMakeLists.txt delete mode 100644 cmake/cmake-cxx11/Tests/Module/CXX11Features/cxx11features.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 74291351..f570479f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ # http://www.cmake.org # -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6 FATAL_ERROR) +CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR) INCLUDE(cmake/Utils.cmake) @@ -68,6 +68,11 @@ SET(VMIME_API_VERSION ${VMIME_API_VERSION_CURRENT}.${VMIME_API_VERSION_REVISION} # Set base name SET(VMIME_LIBRARY_NAME vmime) +# Enable C++11 +SET(CMAKE_CXX_STANDARD 11) +SET(CMAKE_CXX_STANDARD_REQUIRED ON) +SET(CMAKE_CXX_EXTENSIONS OFF) + # Source files FILE( GLOB_RECURSE @@ -795,89 +800,6 @@ ELSE() ENDIF() -############################################################################## -# Language features - -# C++11 -INCLUDE(cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake) - -# Smart pointers -# -# If a C++11-compliant compiler is available and supports std::shared_ptr<>, -# use the standard implementation. Else, use boost::shared_ptr<>. -# In any case, let the user override the choice with VMIME_SHARED_PTR_USE_CXX -# and VMIME_SHARED_PTR_USE_BOOST variables. - -CHECK_CXX_SOURCE_COMPILES( - " - #include - struct A { int foo; }; - int main() { - std::shared_ptr a = std::make_shared (); - return 0; - } - " - VMIME_HAS_CXX11_SHARED_PTR -) - -IF(NOT VMIME_SHARED_PTR_USE_CXX AND NOT VMIME_SHARED_PTR_USE_BOOST) - IF(CXX11_COMPILER_FLAGS AND VMIME_HAS_CXX11_SHARED_PTR) - # If std::shared_ptr<> is available, use it by default - SET(VMIME_SHARED_PTR_USE_CXX_DEFAULT ON) - SET(VMIME_SHARED_PTR_USE_BOOST_DEFAULT OFF) - ELSE() - # Else, set default to boost::shared_ptr<> - SET(VMIME_SHARED_PTR_USE_CXX_DEFAULT OFF) - SET(VMIME_SHARED_PTR_USE_BOOST_DEFAULT ON) - ENDIF() -ENDIF() - -OPTION( - VMIME_SHARED_PTR_USE_CXX - "Use standard std::shared_ptr<> (requires a C++11 compiler)" - ${VMIME_SHARED_PTR_USE_CXX_DEFAULT} -) - -OPTION( - VMIME_SHARED_PTR_USE_BOOST - "Use boost::shared_ptr<> (requires Boost)" - ${VMIME_SHARED_PTR_USE_BOOST_DEFAULT} -) - -IF(VMIME_SHARED_PTR_USE_CXX AND VMIME_SHARED_PTR_USE_BOOST) - MESSAGE(FATAL_ERROR "Options VMIME_SHARED_PTR_USE_CXX and VMIME_SHARED_PTR_USE_BOOST are mutually exclusive (select one or the other, but not both!)") -ENDIF() - -IF(VMIME_SHARED_PTR_USE_CXX) - - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}") - - IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - ENDIF() - - MESSAGE(STATUS "Checking support for shared_ptr<>: built-in (C++11)") - -ELSEIF(VMIME_SHARED_PTR_USE_BOOST) - - # Depends on Boost library if C++11 is not supported - FIND_PACKAGE(Boost) - - IF(Boost_FOUND) - INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) - ELSE() - MESSAGE(FATAL_ERROR "Boost library is required for shared_ptr<>, unless you compile using C++11") - ENDIF() - - MESSAGE(STATUS "Checking support for shared_ptr<>: boost library") - -ELSE() - - MESSAGE(FATAL_ERROR "No implementation for shared_ptr<> was selected/found") - -ENDIF() - - ############################################################################## # Platform diff --git a/cmake/cmake-cxx11/.gitignore b/cmake/cmake-cxx11/.gitignore deleted file mode 100644 index 378eac25..00000000 --- a/cmake/cmake-cxx11/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build diff --git a/cmake/cmake-cxx11/MERGE-TODO b/cmake/cmake-cxx11/MERGE-TODO deleted file mode 100644 index dc2ce480..00000000 --- a/cmake/cmake-cxx11/MERGE-TODO +++ /dev/null @@ -1,7 +0,0 @@ -These things need to be changed when this module is merged into CMake: - --change include(CheckCXXCompilerFlag) in CheckCXX11Features.cmake to - include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXCompilerFlag.cmake) --remove the setting of CMAKE_MODULE_PATH from the testcase CMakeLists.txt --change all tabs to spaces in the cpp files - diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake b/cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake deleted file mode 100644 index bef7ef93..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake +++ /dev/null @@ -1,142 +0,0 @@ -# - Check which parts of the C++11 standard the compiler supports -# -# When found it will set the following variables -# -# CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features -# -# HAS_CXX11_AUTO - auto keyword -# HAS_CXX11_AUTO_RET_TYPE - function declaration with deduced return types -# HAS_CXX11_CLASS_OVERRIDE - override and final keywords for classes and methods -# HAS_CXX11_CONSTEXPR - constexpr keyword -# HAS_CXX11_CSTDINT_H - cstdint header -# HAS_CXX11_DECLTYPE - decltype keyword -# HAS_CXX11_FUNC - __func__ preprocessor constant -# HAS_CXX11_INITIALIZER_LIST - initializer list -# HAS_CXX11_LAMBDA - lambdas -# HAS_CXX11_LIB_REGEX - regex library -# HAS_CXX11_LONG_LONG - long long signed & unsigned types -# HAS_CXX11_NULLPTR - nullptr -# HAS_CXX11_RVALUE_REFERENCES - rvalue references -# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members -# HAS_CXX11_STATIC_ASSERT - static_assert() -# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates - -#============================================================================= -# Copyright 2011,2012 Rolf Eike Beer -# Copyright 2012 Andreas Weis -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -# -# Each feature may have up to 3 checks, every one of them in it's own file -# FEATURE.cpp - example that must build and return 0 when run -# FEATURE_fail.cpp - example that must build, but may not return 0 when run -# FEATURE_fail_compile.cpp - example that must fail compilation -# -# The first one is mandatory, the latter 2 are optional and do not depend on -# each other (i.e. only one may be present). -# - -if (NOT CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "CheckCXX11Features modules only works if language CXX is enabled") -endif () - -cmake_minimum_required(VERSION 2.8.3) - -# -### Check for needed compiler flags -# -include(CheckCXXCompilerFlag) -check_cxx_compiler_flag("-std=c++11" _HAS_CXX11_FLAG) -if (NOT _HAS_CXX11_FLAG) - check_cxx_compiler_flag("-std=c++0x" _HAS_CXX0X_FLAG) -endif () - -if (_HAS_CXX11_FLAG) - set(CXX11_COMPILER_FLAGS "-std=c++11") -elseif (_HAS_CXX0X_FLAG) - set(CXX11_COMPILER_FLAGS "-std=c++0x") -endif () - -function(cxx11_check_feature FEATURE_NAME RESULT_VAR) - if (NOT DEFINED ${RESULT_VAR}) - set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11_${FEATURE_NAME}") - - set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXX11Features/cxx11-test-${FEATURE_NAME}) - set(_LOG_NAME "\"${FEATURE_NAME}\"") - message(STATUS "Checking C++11 support for ${_LOG_NAME}") - - set(_SRCFILE "${_SRCFILE_BASE}.cpp") - set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp") - set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp") - - if (CMAKE_CROSSCOMPILING) - try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}" - COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") - if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) - try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}" - COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") - endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) - else (CMAKE_CROSSCOMPILING) - try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR - "${_bindir}" "${_SRCFILE}" - COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") - if (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) - set(${RESULT_VAR} TRUE) - else (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) - set(${RESULT_VAR} FALSE) - endif (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) - if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) - try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR - "${_bindir}_fail" "${_SRCFILE_FAIL}" - COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") - if (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) - set(${RESULT_VAR} TRUE) - else (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) - set(${RESULT_VAR} FALSE) - endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) - endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) - endif (CMAKE_CROSSCOMPILING) - if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) - try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}" - COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}") - if (_TMP_RESULT) - set(${RESULT_VAR} FALSE) - else (_TMP_RESULT) - set(${RESULT_VAR} TRUE) - endif (_TMP_RESULT) - endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) - - if (${RESULT_VAR}) - message(STATUS "Checking C++11 support for ${_LOG_NAME}: works") - else (${RESULT_VAR}) - message(STATUS "Checking C++11 support for ${_LOG_NAME}: not supported") - endif (${RESULT_VAR}) - set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}") - endif (NOT DEFINED ${RESULT_VAR}) -endfunction(cxx11_check_feature) - -cxx11_check_feature("__func__" HAS_CXX11_FUNC) -cxx11_check_feature("auto" HAS_CXX11_AUTO) -cxx11_check_feature("auto_ret_type" HAS_CXX11_AUTO_RET_TYPE) -cxx11_check_feature("class_override_final" HAS_CXX11_CLASS_OVERRIDE) -cxx11_check_feature("constexpr" HAS_CXX11_CONSTEXPR) -cxx11_check_feature("cstdint" HAS_CXX11_CSTDINT_H) -cxx11_check_feature("decltype" HAS_CXX11_DECLTYPE) -cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST) -cxx11_check_feature("lambda" HAS_CXX11_LAMBDA) -cxx11_check_feature("long_long" HAS_CXX11_LONG_LONG) -cxx11_check_feature("nullptr" HAS_CXX11_NULLPTR) -cxx11_check_feature("regex" HAS_CXX11_LIB_REGEX) -cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES) -cxx11_check_feature("sizeof_member" HAS_CXX11_SIZEOF_MEMBER) -cxx11_check_feature("static_assert" HAS_CXX11_STATIC_ASSERT) -cxx11_check_feature("variadic_templates" HAS_CXX11_VARIADIC_TEMPLATES) diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-__func__.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-__func__.cpp deleted file mode 100644 index 3bfd8a89..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-__func__.cpp +++ /dev/null @@ -1,8 +0,0 @@ -int main(void) -{ - if (!__func__) - return 1; - if (!(*__func__)) - return 1; - return 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto.cpp deleted file mode 100644 index 948648e9..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto.cpp +++ /dev/null @@ -1,12 +0,0 @@ - -int main() -{ - auto i = 5; - auto f = 3.14159f; - auto d = 3.14159; - bool ret = ( - (sizeof(f) < sizeof(d)) && - (sizeof(i) == sizeof(int)) - ); - return ret ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_fail_compile.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_fail_compile.cpp deleted file mode 100644 index 3c0e3f2e..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_fail_compile.cpp +++ /dev/null @@ -1,7 +0,0 @@ -int main(void) -{ - // must fail because there is no initializer - auto i; - - return 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_ret_type.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_ret_type.cpp deleted file mode 100644 index 937b6835..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-auto_ret_type.cpp +++ /dev/null @@ -1,8 +0,0 @@ -auto foo(int i) -> int { - return i - 1; -} - -int main() -{ - return foo(1); -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final.cpp deleted file mode 100644 index f5870b19..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final.cpp +++ /dev/null @@ -1,21 +0,0 @@ -class base { -public: - virtual int foo(int a) - { return 4 + a; } - int bar(int a) final - { return a - 2; } -}; - -class sub final : public base { -public: - virtual int foo(int a) override - { return 8 + 2 * a; }; -}; - -int main(void) -{ - base b; - sub s; - - return (b.foo(2) * 2 == s.foo(2)) ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final_fail_compile.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final_fail_compile.cpp deleted file mode 100644 index bc00b278..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-class_override_final_fail_compile.cpp +++ /dev/null @@ -1,25 +0,0 @@ -class base { -public: - virtual int foo(int a) - { return 4 + a; } - virtual int bar(int a) final - { return a - 2; } -}; - -class sub final : public base { -public: - virtual int foo(int a) override - { return 8 + 2 * a; }; - virtual int bar(int a) - { return a; } -}; - -class impossible : public sub { }; - -int main(void) -{ - base b; - sub s; - - return 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-constexpr.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-constexpr.cpp deleted file mode 100644 index ed624512..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-constexpr.cpp +++ /dev/null @@ -1,19 +0,0 @@ -constexpr int square(int x) -{ - return x*x; -} - -constexpr int the_answer() -{ - return 42; -} - -int main() -{ - int test_arr[square(3)]; - bool ret = ( - (square(the_answer()) == 1764) && - (sizeof(test_arr)/sizeof(test_arr[0]) == 9) - ); - return ret ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-cstdint.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-cstdint.cpp deleted file mode 100644 index ca2c72dd..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-cstdint.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -int main() -{ - bool test = - (sizeof(int8_t) == 1) && - (sizeof(int16_t) == 2) && - (sizeof(int32_t) == 4) && - (sizeof(int64_t) == 8); - return test ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-decltype.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-decltype.cpp deleted file mode 100644 index 0dbb1cc5..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-decltype.cpp +++ /dev/null @@ -1,10 +0,0 @@ -bool check_size(int i) -{ - return sizeof(int) == sizeof(decltype(i)); -} - -int main() -{ - bool ret = check_size(42); - return ret ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-initializer_list.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-initializer_list.cpp deleted file mode 100644 index 35e6c384..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-initializer_list.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -class seq { -public: - seq(std::initializer_list list); - - int length() const; -private: - std::vector m_v; -}; - -seq::seq(std::initializer_list list) - : m_v(list) -{ -} - -int seq::length() const -{ - return m_v.size(); -} - -int main(void) -{ - seq a = {18, 20, 2, 0, 4, 7}; - - return (a.length() == 6) ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-lambda.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-lambda.cpp deleted file mode 100644 index 4c33ed58..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-lambda.cpp +++ /dev/null @@ -1,5 +0,0 @@ -int main() -{ - int ret = 0; - return ([&ret]() -> int { return ret; })(); -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-long_long.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-long_long.cpp deleted file mode 100644 index 09111275..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-long_long.cpp +++ /dev/null @@ -1,7 +0,0 @@ -int main(void) -{ - long long l; - unsigned long long ul; - - return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr.cpp deleted file mode 100644 index 9f410715..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr.cpp +++ /dev/null @@ -1,6 +0,0 @@ -int main(void) -{ - void *v = nullptr; - - return v ? 1 : 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr_fail_compile.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr_fail_compile.cpp deleted file mode 100644 index 6a002bcb..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-nullptr_fail_compile.cpp +++ /dev/null @@ -1,6 +0,0 @@ -int main(void) -{ - int i = nullptr; - - return 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-regex.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-regex.cpp deleted file mode 100644 index 2fe01c4f..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-regex.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -int parse_line(std::string const& line) -{ - std::string tmp; - if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+//(-)?(\\d)+(\\s)+"))) { - tmp = std::regex_replace(line, std::regex("(-)?(\\d)+//(-)?(\\d)+"), std::string("V")); - } else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) { - tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+"), std::string("V")); - } else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) { - tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+"), std::string("V")); - } else { - tmp = std::regex_replace(line, std::regex("(-)?(\\d)+"), std::string("V")); - } - return static_cast(std::count(tmp.begin(), tmp.end(), 'V')); -} - -int main() -{ - bool test = (parse_line("f 7/7/7 -3/3/-3 2/-2/2") == 3) && - (parse_line("f 7//7 3//-3 -2//2") == 3) && - (parse_line("f 7/7 3/-3 -2/2") == 3) && - (parse_line("f 7 3 -2") == 3); - return test ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-rvalue-references.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-rvalue-references.cpp deleted file mode 100644 index e6e7e5a9..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-rvalue-references.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include - -class rvmove { -public: - void *ptr; - char *array; - - rvmove() - : ptr(0), - array(new char[10]) - { - ptr = this; - } - - rvmove(rvmove &&other) - : ptr(other.ptr), - array(other.array) - { - other.array = 0; - other.ptr = 0; - } - - ~rvmove() - { - assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0))); - delete[] array; - } - - rvmove &operator=(rvmove &&other) - { - delete[] array; - ptr = other.ptr; - array = other.array; - other.array = 0; - other.ptr = 0; - return *this; - } - - static rvmove create() - { - return rvmove(); - } -private: - rvmove(const rvmove &); - rvmove &operator=(const rvmove &); -}; - -int main() -{ - rvmove mine; - if (mine.ptr != &mine) - return 1; - mine = rvmove::create(); - if (mine.ptr == &mine) - return 1; - return 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member.cpp deleted file mode 100644 index 4902fc73..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member.cpp +++ /dev/null @@ -1,14 +0,0 @@ -struct foo { - char bar; - int baz; -}; - -int main(void) -{ - bool ret = ( - (sizeof(foo::bar) == 1) && - (sizeof(foo::baz) >= sizeof(foo::bar)) && - (sizeof(foo) >= sizeof(foo::bar) + sizeof(foo::baz)) - ); - return ret ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member_fail.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member_fail.cpp deleted file mode 100644 index 0348c2ce..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-sizeof_member_fail.cpp +++ /dev/null @@ -1,9 +0,0 @@ -struct foo { - int baz; - double bar; -}; - -int main(void) -{ - return (sizeof(foo::bar) == 4) ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert.cpp deleted file mode 100644 index 47c2fefb..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert.cpp +++ /dev/null @@ -1,5 +0,0 @@ -int main(void) -{ - static_assert(0 < 1, "your ordering of integers is screwed"); - return 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert_fail_compile.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert_fail_compile.cpp deleted file mode 100644 index 362fcdde..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-static_assert_fail_compile.cpp +++ /dev/null @@ -1,5 +0,0 @@ -int main(void) -{ - static_assert(1 < 0, "your ordering of integers is screwed"); - return 0; -} diff --git a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-variadic_templates.cpp b/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-variadic_templates.cpp deleted file mode 100644 index 4518e886..00000000 --- a/cmake/cmake-cxx11/Modules/CheckCXX11Features/cxx11-test-variadic_templates.cpp +++ /dev/null @@ -1,23 +0,0 @@ -int Accumulate() -{ - return 0; -} - -template -int Accumulate(T v, Ts... vs) -{ - return v + Accumulate(vs...); -} - -template -int CountElements() -{ - return sizeof...(Is); -} - -int main() -{ - int acc = Accumulate(1, 2, 3, 4, -5); - int count = CountElements<1,2,3,4,5>(); - return ((acc == 5) && (count == 5)) ? 0 : 1; -} diff --git a/cmake/cmake-cxx11/Tests/Module/CXX11Features/CMakeLists.txt b/cmake/cmake-cxx11/Tests/Module/CXX11Features/CMakeLists.txt deleted file mode 100644 index f117eb16..00000000 --- a/cmake/cmake-cxx11/Tests/Module/CXX11Features/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) -project(Cxx11Features CXX) - -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules") - -include(CheckCXX11Features) - -foreach (flag IN ITEMS - HAS_CXX11_AUTO - HAS_CXX11_AUTO_RET_TYPE - HAS_CXX11_CLASS_OVERRIDE - HAS_CXX11_CONSTEXPR - HAS_CXX11_CSTDINT_H - HAS_CXX11_DECLTYPE - HAS_CXX11_FUNC - HAS_CXX11_INITIALIZER_LIST - HAS_CXX11_LAMBDA - HAS_CXX11_LIB_REGEX - HAS_CXX11_LONG_LONG - HAS_CXX11_NULLPTR - HAS_CXX11_RVALUE_REFERENCES - HAS_CXX11_SIZEOF_MEMBER - HAS_CXX11_STATIC_ASSERT - HAS_CXX11_VARIADIC_TEMPLATES - ) - if (${flag}) - add_definitions("-D${flag}") - message(STATUS "Compiler C++11 support flag ${flag} set") - endif () -endforeach (flag) - -set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}) -add_executable(CXX11Features cxx11features.cxx) diff --git a/cmake/cmake-cxx11/Tests/Module/CXX11Features/cxx11features.cxx b/cmake/cmake-cxx11/Tests/Module/CXX11Features/cxx11features.cxx deleted file mode 100644 index c09038fb..00000000 --- a/cmake/cmake-cxx11/Tests/Module/CXX11Features/cxx11features.cxx +++ /dev/null @@ -1,57 +0,0 @@ -#if defined(HAS_CXX0X_CSTDINT_H) -#include -#endif - -#include - -struct thing { - unsigned char one; -#if defined(HAS_CXX0X_CSTDINT_H) - uint32_t four; -#endif -#if defined(HAS_CXX0X_LONG_LONG) - long long eight; -#endif -}; - -#include - -int main() -{ -#if defined (HAS_CXX0X_NULLPTR) - void *nix = nullptr; -#else /* HAS_CXX0X_NULLPTR */ - void *nix = 0; -#endif /* HAS_CXX0X_NULLPTR */ - -#if defined(HAS_CXX0X_STATIC_ASSERT) - static_assert(1 < 42, "Your C++ compiler is b0rked"); -#endif /* HAS_CXX0X_STATIC_ASSERT */ - -#if defined(HAS_CXX0X_FUNC) - const char *funcname = __func__; - printf("the name of main() function is: %s\n", funcname); -#endif /* HAS_CXX0X_FUNC */ - -#if defined(HAS_CXX0X_SIZEOF_MEMBER) - size_t onesize = sizeof(thing::one); -#if defined(HAS_CXX0X_STATIC_ASSERT) - static_assert(sizeof(thing::one) == 1, "Your char is not one byte long"); -#endif /* HAS_CXX0X_STATIC_ASSERT */ - -#if defined(HAS_CXX0X_CSTDINT_H) - size_t foursize = sizeof(thing::four); -#if defined(HAS_CXX0X_STATIC_ASSERT) - static_assert(sizeof(thing::four) == 4, "Your uint32_t is not 32 bit long"); -#endif /* HAS_CXX0X_STATIC_ASSERT */ -#endif /* HAS_CXX0X_CSTDINT_H */ -#if defined(HAS_CXX0X_LONG_LONG) - size_t eightsize = sizeof(thing::eight); -#if defined(HAS_CXX0X_STATIC_ASSERT) - static_assert(sizeof(thing::eight) == 8, "Your long long is not 64 bit long"); -#endif /* HAS_CXX0X_STATIC_ASSERT */ -#endif /* HAS_CXX0X_LONG_LONG */ -#endif /* HAS_CXX0X_SIZEOF_MEMBER */ - - return 0; -} diff --git a/doc/book/building.tex b/doc/book/building.tex index 415f707a..9feeedcb 100644 --- a/doc/book/building.tex +++ b/doc/book/building.tex @@ -25,8 +25,6 @@ want SASL\footnote{Simple Authentication and Security Layer} support ; \item either the \href{http://www.openssl.org}{OpenSSL library} or the \href{http://www.gnu.org/software/gnutls/}{GNU TLS Library} if you want SSL and TLS\footnote{Transport Layer Security} support ; -\item the \href{http://www.boost.org}{Boost C++ library} if you are not using -C++11 (or your compiler does not support it), for {\vcode shared\_ptr<>}. \end{itemize} % ============================================================================ diff --git a/src/vmime/types.hpp b/src/vmime/types.hpp index 7e5b7ee8..7f2a0354 100644 --- a/src/vmime/types.hpp +++ b/src/vmime/types.hpp @@ -31,42 +31,24 @@ #include #include #include +#include #include "vmime/config.hpp" #ifndef VMIME_BUILDING_DOC -#if VMIME_SHARED_PTR_USE_CXX - // If we are compiling with C++11, use shared_ptr<> from the standard lib - #include - - #define VMIME_SHARED_PTR_NAMESPACE std -#elif VMIME_SHARED_PTR_USE_BOOST - // Else, use boost's shared_ptr<> - #include - #include - #include - #include - #include - #include - - #define VMIME_SHARED_PTR_NAMESPACE boost -#else - #error Either VMIME_SHAREDPTR_USE_CXX or VMIME_SHAREDPTR_USE_BOOST must be set to ON -#endif - namespace vmime { - using VMIME_SHARED_PTR_NAMESPACE::shared_ptr; - using VMIME_SHARED_PTR_NAMESPACE::weak_ptr; - using VMIME_SHARED_PTR_NAMESPACE::make_shared; - using VMIME_SHARED_PTR_NAMESPACE::enable_shared_from_this; - using VMIME_SHARED_PTR_NAMESPACE::dynamic_pointer_cast; - using VMIME_SHARED_PTR_NAMESPACE::const_pointer_cast; + using std::shared_ptr; + using std::weak_ptr; + using std::make_shared; + using std::enable_shared_from_this; + using std::dynamic_pointer_cast; + using std::const_pointer_cast; /** Custom deleter to be used with shared_ptr. - * This is does not actually delete the pointer, and is used + * This does not actually delete the pointer, and is used * only for the singleton classes allocated on the stack. */ template @@ -75,15 +57,9 @@ namespace vmime void operator()(T*) const {} }; -#if VMIME_SHARED_PTR_USE_CXX template using scoped_ptr = std::unique_ptr ; -#else - using VMIME_SHARED_PTR_NAMESPACE::scoped_ptr; -#endif } -#undef VMIME_SHARED_PTR_NAMESPACE - #endif // VMIME_BUILDING_DOC @@ -103,16 +79,6 @@ namespace vmime // For compatibility with versions <= 0.7.1 (deprecated) namespace net { } namespace messaging = net; - - // For (minimal) compatibility with legacy smart pointers (<= 0.9.1) - // Your compiler must have support for C++11 -#if VMIME_COMPAT_LEGACY_SMART_POINTERS - template using ref = shared_ptr ; - class creator {}; // unused - template - inline shared_ptr create(Args&&... args) { return make_shared (args...); } -#endif - } From 8495ce11160ea0fb15d4f9edd105239bb9bd9901 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Wed, 4 Apr 2018 20:10:28 +0200 Subject: [PATCH 10/27] #194 Fixed documentation --- doc/book/start.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/book/start.tex b/doc/book/start.tex index 2983bbfc..74084941 100644 --- a/doc/book/start.tex +++ b/doc/book/start.tex @@ -26,7 +26,7 @@ You can simply build your program with: to use the static version, or with: \begin{verbatim} - $ g++ `pkg-config --cflags --libs vmime` -o myprog myprog.cpp + $ g++ `pkg-config --cflags vmime` -o myprog myprog.cpp `pkg-config --libs vmime` \end{verbatim} to use the shared version. From a9b822140bf8926620fd21b880893d4c214dd8c0 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Tue, 24 Apr 2018 20:31:26 +0200 Subject: [PATCH 11/27] #196 Allow overriding CMAKE_CXX_FLAGS --- CMakeLists.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f570479f..a03d0f95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -931,12 +931,12 @@ IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") SET( CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -D_REENTRANT=1 -W -Wall -pedantic -Warray-bounds-pointer-arithmetic -Wold-style-cast -Wconversion -Wcast-align -Wno-sign-conversion" + "-D_REENTRANT=1 -W -Wall -pedantic -Warray-bounds-pointer-arithmetic -Wold-style-cast -Wconversion -Wcast-align -Wno-sign-conversion ${CMAKE_CXX_FLAGS}" ) - SET(CMAKE_CXX_FLAGS_RELEASE "-O2") - SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") + SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}") + SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") #SET(CMAKE_EXE_LINKER_FLAGS "-s") @@ -946,12 +946,12 @@ ELSE() SET( CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -D_REENTRANT=1 -W -Wall -pedantic -Wpointer-arith -Wold-style-cast -Wconversion -Wcast-align -Wno-long-long" + "-D_REENTRANT=1 -W -Wall -pedantic -Wpointer-arith -Wold-style-cast -Wconversion -Wcast-align -Wno-long-long ${CMAKE_CXX_FLAGS}" ) - SET(CMAKE_CXX_FLAGS_RELEASE "-O2") - SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") - SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") + SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}") + SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") #SET(CMAKE_EXE_LINKER_FLAGS "-s") From 6ad4c1a0d5866e9fe314815da5d4caad92d8cbd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Gu=C3=A9rin?= Date: Wed, 30 May 2018 20:20:56 -0400 Subject: [PATCH 12/27] Fix X509Certificate::getIssuerString signature --- src/vmime/security/cert/X509Certificate.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp index d816646b..edc04816 100644 --- a/src/vmime/security/cert/X509Certificate.hpp +++ b/src/vmime/security/cert/X509Certificate.hpp @@ -106,7 +106,7 @@ public: * * @return distinguished name of the certificate issuer, as a string */ - const string getIssuerString() const; + virtual const string getIssuerString() const = 0; /** Checks if this certificate has the given issuer. * From df8051d8dbad358d839bbf538af3617a7b27c8e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Gu=C3=A9rin?= Date: Wed, 30 May 2018 22:07:41 -0400 Subject: [PATCH 13/27] Import multiple certificates withing a single stream --- src/vmime/security/cert/X509Certificate.hpp | 17 +++++++ .../cert/gnutls/X509Certificate_GnuTLS.cpp | 48 +++++++++++++++++++ .../cert/openssl/X509Certificate_OpenSSL.cpp | 35 ++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp index edc04816..de3f8c5e 100644 --- a/src/vmime/security/cert/X509Certificate.hpp +++ b/src/vmime/security/cert/X509Certificate.hpp @@ -85,6 +85,23 @@ public: */ static shared_ptr import(const byte_t* data, const size_t length); + /** Imports a DER or PEM encoded X.509 certificate. + * + * @param is input stream to read data from + * @param certs the resulting list of certificates + */ + static void import(utility::inputStream& is, + std::vector >& certs); + + /** Imports a DER or PEM encoded X.509 certificate. + * + * @param data points to raw data + * @param length size of data + * @param certs the resulting list of certificates + */ + static void import(const byte_t* data, const size_t length, + std::vector >& certs); + /** Exports this X.509 certificate to the specified format. * * @param os output stream into which write data diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp index 85cfb1de..5aec5b1c 100644 --- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp @@ -56,6 +56,11 @@ struct GnuTLSX509CertificateInternalData gnutls_x509_crt_deinit(cert); } + void swap(gnutls_x509_crt_t to) { + gnutls_x509_crt_deinit(cert); + cert = to; + } + gnutls_x509_crt_t cert; }; @@ -128,6 +133,49 @@ shared_ptr X509Certificate::import } +// static +void X509Certificate::import(utility::inputStream& is, + std::vector >& certs) +{ + byteArray bytes; + byte_t chunk[4096]; + + while (!is.eof()) + { + const size_t len = is.read(chunk, sizeof(chunk)); + bytes.insert(bytes.end(), chunk, chunk + len); + } + + import(&bytes[0], bytes.size(), certs); +} + + +// static +void X509Certificate::import(const byte_t* data, const size_t length, + std::vector >& certs) +{ + gnutls_datum_t buffer; + buffer.data = const_cast (data); + buffer.size = static_cast (length); + + unsigned int size = 1024; + gnutls_x509_crt_t x509[1024]; + + // Try DER format + if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_DER, 0) < 0) + + // Try PEM format + if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_PEM, 0) < 0) + return; + + for (unsigned int i = 0; i < size; i += 1) { + auto c = make_shared (); + c->m_data->swap(x509[i]); + certs.push_back(c); + } +} + + void X509Certificate_GnuTLS::write (utility::outputStream& os, const Format format) const { diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp index 90de3568..fd06dfdd 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -218,6 +218,41 @@ shared_ptr X509Certificate::import } +// static +void X509Certificate::import(utility::inputStream& is, + std::vector >& certs) +{ + byteArray bytes; + byte_t chunk[4096]; + + while (!is.eof()) + { + const size_t len = is.read(chunk, sizeof(chunk)); + bytes.insert(bytes.end(), chunk, chunk + len); + } + + import(&bytes[0], bytes.size(), certs); +} + + +// static +void X509Certificate::import(const byte_t* data, const size_t length, + std::vector >& certs) +{ + + BIO* membio = BIO_new_mem_buf(const_cast (data), static_cast (length)); + shared_ptr cert = null; + + while (true) { + cert = make_shared (); + if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) break; + certs.push_back(cert); + } + + BIO_vfree(membio); +} + + void X509Certificate_OpenSSL::write (utility::outputStream& os, const Format format) const { From 52042b2b5b8682eab93786e4337bd0cff6e0ab10 Mon Sep 17 00:00:00 2001 From: 0xd34df00d <0xd34df00d@gmail.com> Date: Wed, 4 Jul 2018 16:03:49 -0400 Subject: [PATCH 14/27] Added net::message::getName() + the IMAP implementation. --- src/vmime/net/imap/IMAPMessagePart.cpp | 10 ++++++++++ src/vmime/net/imap/IMAPMessagePart.hpp | 2 ++ src/vmime/net/message.cpp | 5 +++++ src/vmime/net/message.hpp | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/src/vmime/net/imap/IMAPMessagePart.cpp b/src/vmime/net/imap/IMAPMessagePart.cpp index 1539f2ca..54c29a9e 100644 --- a/src/vmime/net/imap/IMAPMessagePart.cpp +++ b/src/vmime/net/imap/IMAPMessagePart.cpp @@ -68,6 +68,11 @@ IMAPMessagePart::IMAPMessagePart(shared_ptr parent, const size part->body_type_basic()->media_basic()->media_subtype()->value()); m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value(); + + if (const auto pparam = part->body_type_basic()->body_fields()->body_fld_param()) + for (const auto& param : pparam->items()) + if (param->string1()->value() == "NAME") + m_name = param->string2()->value(); } m_structure = null; @@ -115,6 +120,11 @@ size_t IMAPMessagePart::getNumber() const return m_number; } +string IMAPMessagePart::getName() const +{ + return m_name; +} + shared_ptr IMAPMessagePart::getHeader() const { diff --git a/src/vmime/net/imap/IMAPMessagePart.hpp b/src/vmime/net/imap/IMAPMessagePart.hpp index 3b00887b..2e19f551 100644 --- a/src/vmime/net/imap/IMAPMessagePart.hpp +++ b/src/vmime/net/imap/IMAPMessagePart.hpp @@ -59,6 +59,7 @@ public: const mediaType& getType() const; size_t getSize() const; size_t getNumber() const; + string getName() const; shared_ptr getHeader() const; @@ -77,6 +78,7 @@ private: size_t m_number; size_t m_size; + string m_name; mediaType m_mediaType; }; diff --git a/src/vmime/net/message.cpp b/src/vmime/net/message.cpp index 6765e73c..1a0c8c2c 100644 --- a/src/vmime/net/message.cpp +++ b/src/vmime/net/message.cpp @@ -36,6 +36,11 @@ namespace vmime { namespace net { +string messagePart::getName() const +{ + return {}; +} + shared_ptr messagePart::getPartAt(const size_t pos) const { return getStructure()->getPartAt(pos); diff --git a/src/vmime/net/message.hpp b/src/vmime/net/message.hpp index 4c64a1cf..ae21f2dd 100644 --- a/src/vmime/net/message.hpp +++ b/src/vmime/net/message.hpp @@ -99,6 +99,16 @@ public: */ virtual size_t getNumber() const = 0; + /** Return the name of this part. In particular, this corresponds to + * the attachment file name for attachment parts. + * + * The part name may be empty if the part does not advertise it or + * if the underlying protocol does not support it. + * + * @return part name + */ + virtual string getName() const; + /** Return the sub-part at the specified position (zero is the * first part). * From f9a4099837621913d855870ffeb91e9e61d79692 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Fri, 17 Aug 2018 20:30:21 +0200 Subject: [PATCH 15/27] Added section about tracing. --- doc/book/net.tex | 111 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/doc/book/net.tex b/doc/book/net.tex index ac3b70c3..361733ed 100644 --- a/doc/book/net.tex +++ b/doc/book/net.tex @@ -1080,3 +1080,114 @@ The following constants are available: \hline \end{tabularx} + +% ============================================================================ +\section{Tracing connection} + +Connection tracing is used to log what is sent and received on the wire +between the client and the server, and may help debugging. + +First, you have to create your own tracer, which must implement the +{\vcode vmime::net::tracer} interface. Here is an example of a tracer which +simply logs to the standard output: + +\begin{lstlisting}[caption={A simple tracer}] +class myTracer : public vmime::net::tracer +{ +public: + + myTracer(const vmime::string& proto, const int connectionId) + : m_proto(proto), m_connectionId(connectionId) + { + } + + // Called by VMime to trace what is sent on the socket + void traceSend(const vmime::string& line) + { + std::cout << "[" << m_proto << ":" << m_connectionId + << "] C: " << line << std::endl; + } + + // Called by VMime to trace what is received from the socket + void traceReceive(const vmime::string& line) + { + std::cout << "[" < < m_proto << ":" << m_connectionId + << "] S: " << line << std::endl; + } + +private: + + const vmime::string m_proto; + const int m_connectionId; +}; +\end{lstlisting} + +Also create a factory class, used to instanciate your tracer objects: + +\begin{lstlisting} +class myTracerFactory : public vmime::net::tracerFactory +{ +public: + + vmime::shared_ptr create + (vmime::shared_ptr serv, + const int connectionId) + { + return vmime::make_shared + (serv->getProtocolName(), connectionId); + } +}; +\end{lstlisting} + +Next, we have to tell VMime to use it. When you create your service +(either store or transport), simply call the {\vcode setTracerFactory} +on the service and pass an instance of your factory class: + +\begin{lstlisting}[caption={Enabling tracer on a connection}] +vmime::shared_ptr store = + session->getStore("imaps://user:password@imap.myserver.com"); + +// Enable tracing communication between client and server +store->setTracerFactory(vmime::make_shared ()); +\end{lstlisting} + +That's all! Now, everything which is sent on/received from the socket +will be logged using your tracer object. Here is an example of a trace +session for IMAP: + +\begin{verbatim} +[imaps:1] S: * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR + LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready. +[imaps:1] C: a001 AUTHENTICATE PLAIN +[imaps:1] S: + +[imaps:1] C: {...SASL exchange: 52 bytes of data...} +[imaps:1] S: a001 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR + LOGIN-REFERRALS ID ENABLE IDLE SORT SPECIAL-USE QUOTA] Logged in +[imaps:1] C: a002 LIST "" "" +[imaps:1] S: * LIST (\Noselect) "." "" +[imaps:1] S: a002 OK List completed. +[imaps:1] C: a003 CAPABILITY +[imaps:1] S: * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR + LOGIN-REFERRALS ID ENABLE IDLE SORT SPECIAL-USE QUOTA +[imaps:1] S: a003 OK Capability completed. +[imaps:1] C: a003 SELECT INBOX (CONDSTORE) +[imaps:1] S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft + $NotJunk NonJunk JunkRecorded $MDNSent NotJunk $Forwarded + Junk $Junk Forwarded $MailFlagBit1) +[imaps:1] S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted + \Seen \Draft $NotJunk NonJunk JunkRecorded $MDNSent NotJunk + $Forwarded Junk $Junk Forwarded $MailFlagBit1 \*)] + Flags permitted. +[imaps:1] S: * 104 EXISTS +[imaps:1] S: * 0 RECENT +[imaps:1] S: * OK [UNSEEN 6] First unseen. +[imaps:1] S: * OK [UIDVALIDITY 1268127585] UIDs valid +[imaps:1] S: * OK [UIDNEXT 32716] Predicted next UID +[imaps:1] S: * OK [HIGHESTMODSEQ 148020] Highest +[imaps:1] S: a003 OK [READ-WRITE] Select completed. +\end{verbatim} + +Please note that no sensitive data (ie. login or password) will be traced. +Same, {\em blob} data such as message content or SASL exchanges will be logged +as a marker which indicates how many bytes were sent/received (eg. "{...SASL +exchange: 52 bytes of data...}""). From 5eae3b1bd6c586dd4910e4107d9cee1870ca68f8 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Fri, 17 Aug 2018 21:10:48 +0200 Subject: [PATCH 16/27] Fixed warnings with GCC 7. --- src/vmime/emailAddress.cpp | 2 ++ src/vmime/net/imap/IMAPParser.hpp | 4 ++++ src/vmime/utility/encoder/qpEncoder.cpp | 3 ++- src/vmime/utility/encoder/uuEncoder.cpp | 14 ++++++-------- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/vmime/emailAddress.cpp b/src/vmime/emailAddress.cpp index a898e1ce..08c7a35b 100644 --- a/src/vmime/emailAddress.cpp +++ b/src/vmime/emailAddress.cpp @@ -218,6 +218,8 @@ void emailAddress::parseImpl else state = State_LocalPartStart; + break; + case State_LocalPartStart: if (c == '"') diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp index 8b24c9ca..bad87769 100644 --- a/src/vmime/net/imap/IMAPParser.hpp +++ b/src/vmime/net/imap/IMAPParser.hpp @@ -1996,6 +1996,8 @@ public: if (name == "marked") m_type = MARKED; + break; + case 'n': if (name == "noinferiors") @@ -2003,6 +2005,8 @@ public: else if (name == "noselect") m_type = NOSELECT; + break; + case 's': if (name == "sent") diff --git a/src/vmime/utility/encoder/qpEncoder.cpp b/src/vmime/utility/encoder/qpEncoder.cpp index fe252c89..d4844ce7 100644 --- a/src/vmime/utility/encoder/qpEncoder.cpp +++ b/src/vmime/utility/encoder/qpEncoder.cpp @@ -508,7 +508,8 @@ size_t qpEncoder::decode(utility::inputStream& in, break; } - // no break here... + outBuffer[outBufferPos++] = c; + break; } default: { diff --git a/src/vmime/utility/encoder/uuEncoder.cpp b/src/vmime/utility/encoder/uuEncoder.cpp index 0375a397..5ee2c2b1 100644 --- a/src/vmime/utility/encoder/uuEncoder.cpp +++ b/src/vmime/utility/encoder/uuEncoder.cpp @@ -296,14 +296,12 @@ size_t uuEncoder::decode(utility::inputStream& in, const size_t n = std::min(inLength - i, static_cast (3)); - switch (n) - { - default: - case 3: outBuffer[j + 2] = static_cast (UUDECODE(c3) << 6 | UUDECODE(c4)); - case 2: outBuffer[j + 1] = static_cast (UUDECODE(c2) << 4 | UUDECODE(c3) >> 2); - case 1: outBuffer[j] = static_cast (UUDECODE(c1) << 2 | UUDECODE(c2) >> 4); - case 0: break; - } + if (n >= 3) + outBuffer[j + 2] = static_cast (UUDECODE(c3) << 6 | UUDECODE(c4)); + if (n >= 2) + outBuffer[j + 1] = static_cast (UUDECODE(c2) << 4 | UUDECODE(c3) >> 2); + if (n >= 1) + outBuffer[j] = static_cast (UUDECODE(c1) << 2 | UUDECODE(c2) >> 4); total += n; } From 1e56a3617d43cb809be23287fd25d423a18e5917 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Fri, 17 Aug 2018 21:22:11 +0200 Subject: [PATCH 17/27] Force classic locale when formatting IMAP UIDs. --- src/vmime/net/imap/IMAPUtils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vmime/net/imap/IMAPUtils.cpp b/src/vmime/net/imap/IMAPUtils.cpp index 6124edcf..3e6b2677 100644 --- a/src/vmime/net/imap/IMAPUtils.cpp +++ b/src/vmime/net/imap/IMAPUtils.cpp @@ -694,6 +694,7 @@ public: IMAPUIDMessageSetEnumerator() : m_first(true) { + m_oss.imbue(std::locale::classic()); } void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) From 81e73c0f56cc6948af28afc56acb79afd7088f9b Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Fri, 17 Aug 2018 21:29:02 +0200 Subject: [PATCH 18/27] Fixed compilation errors with OpenSSL 1.1.0. --- .../net/tls/openssl/TLSSocket_OpenSSL.cpp | 77 +++++++++++++++---- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp index a663f196..827dcf1b 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp @@ -52,6 +52,8 @@ namespace tls { static OpenSSLInitializer::autoInitializer openSSLInitializer; +#if OPENSSL_VERSION_NUMBER < 0x10100000L + // static BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = { @@ -67,6 +69,22 @@ BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = 0 }; +#define BIO_set_init(b, val) b->init = val +#define BIO_set_data(b, val) b->ptr = val +#define BIO_set_num(b, val) b->num = val +#define BIO_set_flags(b, val) b->flags = val +#define BIO_set_shutdown(b, val) b->shutdown = val +#define BIO_get_init(b) b->init +#define BIO_get_data(b) b->ptr +#define BIO_get_shutdown(b) b->shutdown + +#else + +#define BIO_set_num(b, val) + +#endif + + // static shared_ptr TLSSocket::wrap(shared_ptr session, shared_ptr sok) @@ -99,10 +117,41 @@ void TLSSocket_OpenSSL::createSSLHandle() { if (m_wrapped->isConnected()) { + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + BIO* sockBio = BIO_new(&sm_customBIOMethod); sockBio->ptr = this; sockBio->init = 1; +#else + + BIO_METHOD* bioMeth = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "vmime::socket glue"); + + if (!bioMeth) + { + BIO_meth_free(bioMeth); + throw exceptions::tls_exception("BIO_meth_new() failed"); + } + + BIO_meth_set_write(bioMeth, TLSSocket_OpenSSL::bio_write); + BIO_meth_set_read(bioMeth, TLSSocket_OpenSSL::bio_read); + BIO_meth_set_puts(bioMeth, TLSSocket_OpenSSL::bio_puts); + BIO_meth_set_ctrl(bioMeth, TLSSocket_OpenSSL::bio_ctrl); + BIO_meth_set_create(bioMeth, TLSSocket_OpenSSL::bio_create); + BIO_meth_set_destroy(bioMeth, TLSSocket_OpenSSL::bio_destroy); + + BIO* sockBio = BIO_new(bioMeth); + BIO_set_data(sockBio, this); + BIO_set_init(sockBio, 1); + +#endif + + if (!sockBio) + { + throw exceptions::tls_exception("BIO_new() failed"); + } + m_ssl = SSL_new(m_session->getContext()); if (!m_ssl) @@ -538,9 +587,9 @@ int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len) if (buf == NULL || len <= 0) return -1; - TLSSocket_OpenSSL *sok = reinterpret_cast (bio->ptr); + TLSSocket_OpenSSL *sok = reinterpret_cast (BIO_get_data(bio)); - if (!bio->init || !sok) + if (!BIO_get_init(bio) || !sok) return -1; try @@ -573,9 +622,9 @@ int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) if (buf == NULL || len <= 0) return -1; - TLSSocket_OpenSSL *sok = reinterpret_cast (bio->ptr); + TLSSocket_OpenSSL *sok = reinterpret_cast (BIO_get_data(bio)); - if (!bio->init || !sok) + if (!BIO_get_init(bio) || !sok) return -1; try @@ -621,12 +670,12 @@ long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* /* ptr */) case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; + ret = BIO_get_shutdown(bio); break; case BIO_CTRL_SET_CLOSE: - bio->shutdown = static_cast (num); + BIO_set_shutdown(bio, static_cast (num)); break; case BIO_CTRL_PENDING: @@ -654,10 +703,10 @@ long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* /* ptr */) // static int TLSSocket_OpenSSL::bio_create(BIO* bio) { - bio->init = 0; - bio->num = 0; - bio->ptr = NULL; - bio->flags = 0; + BIO_set_init(bio, 0); + BIO_set_num(bio, 0); + BIO_set_data(bio, NULL); + BIO_set_flags(bio, 0); return 1; } @@ -669,11 +718,11 @@ int TLSSocket_OpenSSL::bio_destroy(BIO* bio) if (bio == NULL) return 0; - if (bio->shutdown) + if (BIO_get_shutdown(bio)) { - bio->ptr = NULL; - bio->init = 0; - bio->flags = 0; + BIO_set_data(bio, NULL); + BIO_set_init(bio, 0); + BIO_set_flags(bio, 0); } return 1; From 997616c6291f6d1d219fabbffa030339b097ec0a Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Sat, 18 Aug 2018 13:52:20 +0200 Subject: [PATCH 19/27] Fixed delete array. --- src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp index 90de3568..a05e61d4 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -454,7 +454,7 @@ const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const vmime::string t(dest); BIO_free(out); - delete dest; + delete [] dest; if (t.size() > 0) { From f173b0a535e4d97c3ecd913eafb5e5c40aca2d44 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Sat, 18 Aug 2018 16:08:25 +0200 Subject: [PATCH 20/27] Avoid copy by passing shared_ptr<> with const reference. --- doc/book/net.tex | 8 +++--- examples/example6_authenticator.hpp | 4 +-- examples/example6_certificateVerifier.hpp | 2 +- examples/example6_tracer.hpp | 8 +++--- src/vmime/addressList.cpp | 12 ++++----- src/vmime/addressList.hpp | 12 ++++----- src/vmime/attachment.hpp | 2 +- src/vmime/attachmentHelper.cpp | 14 +++++----- src/vmime/attachmentHelper.hpp | 14 +++++----- src/vmime/base.hpp | 6 ++--- src/vmime/body.cpp | 26 +++++++++---------- src/vmime/body.hpp | 26 +++++++++---------- src/vmime/bodyPart.cpp | 8 +++--- src/vmime/bodyPart.hpp | 8 +++--- src/vmime/bodyPartAttachment.cpp | 4 +-- src/vmime/bodyPartAttachment.hpp | 4 +-- src/vmime/component.cpp | 8 +++--- src/vmime/component.hpp | 8 +++--- src/vmime/defaultAttachment.cpp | 8 +++--- src/vmime/defaultAttachment.hpp | 8 +++--- src/vmime/encoding.cpp | 4 +-- src/vmime/encoding.hpp | 4 +-- src/vmime/fileAttachment.cpp | 10 +++---- src/vmime/fileAttachment.hpp | 10 +++---- src/vmime/fileContentHandler.cpp | 4 +-- src/vmime/fileContentHandler.hpp | 4 +-- src/vmime/generatedMessageAttachment.cpp | 4 +-- src/vmime/generatedMessageAttachment.hpp | 4 +-- src/vmime/header.cpp | 14 +++++----- src/vmime/header.hpp | 14 +++++----- src/vmime/headerField.cpp | 4 +-- src/vmime/headerField.hpp | 4 +-- src/vmime/htmlTextPart.cpp | 14 +++++----- src/vmime/htmlTextPart.hpp | 14 +++++----- src/vmime/mailboxGroup.cpp | 12 ++++----- src/vmime/mailboxGroup.hpp | 12 ++++----- src/vmime/mailboxList.cpp | 12 ++++----- src/vmime/mailboxList.hpp | 12 ++++----- src/vmime/mdn/MDNHelper.cpp | 12 ++++----- src/vmime/mdn/MDNHelper.hpp | 12 ++++----- src/vmime/mdn/receivedMDNInfos.cpp | 2 +- src/vmime/mdn/receivedMDNInfos.hpp | 2 +- src/vmime/mdn/sendableMDNInfos.cpp | 2 +- src/vmime/mdn/sendableMDNInfos.hpp | 2 +- src/vmime/messageBuilder.cpp | 4 +-- src/vmime/messageBuilder.hpp | 4 +-- src/vmime/messageIdSequence.cpp | 12 ++++----- src/vmime/messageIdSequence.hpp | 12 ++++----- src/vmime/messageParser.cpp | 10 +++---- src/vmime/messageParser.hpp | 10 +++---- src/vmime/misc/importanceHelper.cpp | 12 ++++----- src/vmime/misc/importanceHelper.hpp | 12 ++++----- src/vmime/net/events.cpp | 6 ++--- src/vmime/net/events.hpp | 18 ++++++------- src/vmime/net/folder.cpp | 8 +++--- src/vmime/net/folder.hpp | 12 ++++----- src/vmime/net/imap/IMAPCommand.cpp | 2 +- src/vmime/net/imap/IMAPCommand.hpp | 2 +- src/vmime/net/imap/IMAPConnection.cpp | 6 ++--- src/vmime/net/imap/IMAPConnection.hpp | 6 ++--- src/vmime/net/imap/IMAPFolder.cpp | 6 ++--- src/vmime/net/imap/IMAPFolder.hpp | 6 ++--- src/vmime/net/imap/IMAPMessage.cpp | 14 +++++----- src/vmime/net/imap/IMAPMessage.hpp | 14 +++++----- src/vmime/net/imap/IMAPMessagePart.cpp | 6 ++--- src/vmime/net/imap/IMAPMessagePart.hpp | 6 ++--- .../imap/IMAPMessagePartContentHandler.cpp | 2 +- .../imap/IMAPMessagePartContentHandler.hpp | 2 +- src/vmime/net/imap/IMAPMessageStructure.cpp | 2 +- src/vmime/net/imap/IMAPMessageStructure.hpp | 2 +- src/vmime/net/imap/IMAPParser.hpp | 8 +++--- src/vmime/net/imap/IMAPSStore.cpp | 2 +- src/vmime/net/imap/IMAPSStore.hpp | 2 +- src/vmime/net/imap/IMAPStore.cpp | 2 +- src/vmime/net/imap/IMAPStore.hpp | 2 +- src/vmime/net/imap/IMAPUtils.cpp | 4 +-- src/vmime/net/imap/IMAPUtils.hpp | 6 ++--- .../maildir/format/courierMaildirFormat.cpp | 2 +- .../maildir/format/courierMaildirFormat.hpp | 2 +- .../net/maildir/format/kmailMaildirFormat.cpp | 2 +- .../net/maildir/format/kmailMaildirFormat.hpp | 2 +- src/vmime/net/maildir/maildirFolder.cpp | 6 ++--- src/vmime/net/maildir/maildirFolder.hpp | 6 ++--- src/vmime/net/maildir/maildirFormat.cpp | 6 ++--- src/vmime/net/maildir/maildirFormat.hpp | 6 ++--- src/vmime/net/maildir/maildirMessage.cpp | 8 +++--- src/vmime/net/maildir/maildirMessage.hpp | 8 +++--- src/vmime/net/maildir/maildirMessagePart.cpp | 2 +- src/vmime/net/maildir/maildirMessagePart.hpp | 2 +- .../net/maildir/maildirMessageStructure.cpp | 4 +-- .../net/maildir/maildirMessageStructure.hpp | 4 +-- src/vmime/net/maildir/maildirStore.cpp | 2 +- src/vmime/net/maildir/maildirStore.hpp | 2 +- src/vmime/net/maildir/maildirUtils.cpp | 2 +- src/vmime/net/maildir/maildirUtils.hpp | 2 +- src/vmime/net/message.hpp | 4 +-- src/vmime/net/pop3/POP3Command.cpp | 2 +- src/vmime/net/pop3/POP3Command.hpp | 2 +- src/vmime/net/pop3/POP3Connection.cpp | 2 +- src/vmime/net/pop3/POP3Connection.hpp | 2 +- src/vmime/net/pop3/POP3Folder.cpp | 6 ++--- src/vmime/net/pop3/POP3Folder.hpp | 6 ++--- src/vmime/net/pop3/POP3Message.cpp | 8 +++--- src/vmime/net/pop3/POP3Message.hpp | 8 +++--- src/vmime/net/pop3/POP3Response.cpp | 8 +++--- src/vmime/net/pop3/POP3Response.hpp | 8 +++--- src/vmime/net/pop3/POP3SStore.cpp | 2 +- src/vmime/net/pop3/POP3SStore.hpp | 2 +- src/vmime/net/pop3/POP3Store.cpp | 2 +- src/vmime/net/pop3/POP3Store.hpp | 2 +- src/vmime/net/pop3/POP3Utils.cpp | 2 +- src/vmime/net/pop3/POP3Utils.hpp | 2 +- src/vmime/net/sendmail/sendmailTransport.cpp | 4 +-- src/vmime/net/sendmail/sendmailTransport.hpp | 4 +-- src/vmime/net/service.cpp | 14 +++++----- src/vmime/net/service.hpp | 12 ++++----- src/vmime/net/serviceFactory.cpp | 10 +++---- src/vmime/net/serviceFactory.hpp | 14 +++++----- src/vmime/net/serviceInfos.cpp | 2 +- src/vmime/net/serviceInfos.hpp | 4 +-- src/vmime/net/serviceRegistration.inl | 4 +-- src/vmime/net/session.cpp | 14 +++++----- src/vmime/net/session.hpp | 14 +++++----- .../smtp/SMTPChunkingOutputStreamAdapter.cpp | 2 +- .../smtp/SMTPChunkingOutputStreamAdapter.hpp | 2 +- src/vmime/net/smtp/SMTPCommand.cpp | 2 +- src/vmime/net/smtp/SMTPCommand.hpp | 2 +- src/vmime/net/smtp/SMTPCommandSet.cpp | 4 +-- src/vmime/net/smtp/SMTPCommandSet.hpp | 4 +-- src/vmime/net/smtp/SMTPConnection.cpp | 4 +-- src/vmime/net/smtp/SMTPConnection.hpp | 4 +-- src/vmime/net/smtp/SMTPResponse.cpp | 8 +++--- src/vmime/net/smtp/SMTPResponse.hpp | 6 ++--- src/vmime/net/smtp/SMTPSTransport.cpp | 2 +- src/vmime/net/smtp/SMTPSTransport.hpp | 2 +- src/vmime/net/smtp/SMTPTransport.cpp | 4 +-- src/vmime/net/smtp/SMTPTransport.hpp | 4 +-- src/vmime/net/socket.hpp | 4 +-- src/vmime/net/store.hpp | 2 +- .../net/tls/TLSSecuredConnectionInfos.cpp | 2 +- .../net/tls/TLSSecuredConnectionInfos.hpp | 2 +- src/vmime/net/tls/TLSSession.hpp | 4 +-- src/vmime/net/tls/TLSSocket.hpp | 2 +- .../net/tls/gnutls/TLSSession_GnuTLS.cpp | 6 ++--- .../net/tls/gnutls/TLSSession_GnuTLS.hpp | 4 +-- src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp | 6 ++--- src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp | 4 +-- .../net/tls/openssl/TLSSession_OpenSSL.cpp | 6 ++--- .../net/tls/openssl/TLSSession_OpenSSL.hpp | 4 +-- .../net/tls/openssl/TLSSocket_OpenSSL.cpp | 6 ++--- .../net/tls/openssl/TLSSocket_OpenSSL.hpp | 4 +-- src/vmime/net/tracer.hpp | 2 +- src/vmime/net/transport.cpp | 14 +++++----- src/vmime/net/transport.hpp | 10 +++---- src/vmime/parameterizedHeaderField.cpp | 12 ++++----- src/vmime/parameterizedHeaderField.hpp | 12 ++++----- src/vmime/parsedMessageAttachment.cpp | 4 +-- src/vmime/parsedMessageAttachment.hpp | 4 +-- src/vmime/plainTextPart.cpp | 8 +++--- src/vmime/plainTextPart.hpp | 6 ++--- .../platforms/posix/posixChildProcess.cpp | 2 +- .../platforms/posix/posixChildProcess.hpp | 2 +- src/vmime/platforms/posix/posixSocket.cpp | 4 +-- src/vmime/platforms/posix/posixSocket.hpp | 4 +-- src/vmime/platforms/windows/windowsSocket.cpp | 4 +-- src/vmime/platforms/windows/windowsSocket.hpp | 6 ++--- src/vmime/propertySet.hpp | 2 +- src/vmime/security/authenticator.hpp | 2 +- src/vmime/security/cert/X509Certificate.hpp | 4 +-- src/vmime/security/cert/certificate.hpp | 2 +- src/vmime/security/cert/certificateChain.cpp | 2 +- src/vmime/security/cert/certificateChain.hpp | 2 +- .../security/cert/certificateException.cpp | 2 +- .../security/cert/certificateException.hpp | 2 +- .../security/cert/certificateVerifier.hpp | 2 +- .../cert/defaultCertificateVerifier.cpp | 4 +-- .../cert/defaultCertificateVerifier.hpp | 4 +-- .../cert/gnutls/X509Certificate_GnuTLS.cpp | 6 ++--- .../cert/gnutls/X509Certificate_GnuTLS.hpp | 6 ++--- .../cert/openssl/X509Certificate_OpenSSL.cpp | 6 ++--- .../cert/openssl/X509Certificate_OpenSSL.hpp | 6 ++--- src/vmime/security/defaultAuthenticator.cpp | 2 +- src/vmime/security/defaultAuthenticator.hpp | 2 +- src/vmime/security/sasl/SASLAuthenticator.hpp | 6 ++--- src/vmime/security/sasl/SASLContext.cpp | 2 +- src/vmime/security/sasl/SASLContext.hpp | 2 +- src/vmime/security/sasl/SASLMechanism.hpp | 6 ++--- .../security/sasl/SASLMechanismFactory.cpp | 2 +- .../security/sasl/SASLMechanismFactory.hpp | 6 ++--- src/vmime/security/sasl/SASLSession.cpp | 10 +++---- src/vmime/security/sasl/SASLSession.hpp | 10 +++---- src/vmime/security/sasl/SASLSocket.cpp | 4 +-- src/vmime/security/sasl/SASLSocket.hpp | 4 +-- .../sasl/XOAuth2SASLAuthenticator.cpp | 8 +++--- .../sasl/XOAuth2SASLAuthenticator.hpp | 2 +- .../security/sasl/XOAuth2SASLMechanism.cpp | 8 +++--- .../security/sasl/XOAuth2SASLMechanism.hpp | 8 +++--- .../security/sasl/builtinSASLMechanism.cpp | 8 +++--- .../security/sasl/builtinSASLMechanism.hpp | 8 +++--- .../sasl/defaultSASLAuthenticator.cpp | 8 +++--- .../sasl/defaultSASLAuthenticator.hpp | 8 +++--- src/vmime/streamContentHandler.cpp | 4 +-- src/vmime/streamContentHandler.hpp | 4 +-- src/vmime/text.cpp | 6 ++--- src/vmime/text.hpp | 6 ++--- src/vmime/textPart.hpp | 6 ++--- src/vmime/utility/childProcess.hpp | 2 +- .../utility/parserInputStreamAdapter.cpp | 2 +- .../utility/parserInputStreamAdapter.hpp | 2 +- .../seekableInputStreamRegionAdapter.cpp | 2 +- .../seekableInputStreamRegionAdapter.hpp | 2 +- src/vmime/utility/sync/autoLock.hpp | 2 +- tests/parser/attachmentHelperTest.cpp | 4 +-- tests/parser/bodyPartTest.cpp | 2 +- tests/parser/htmlTextPartTest.cpp | 2 +- tests/testUtils.cpp | 2 +- tests/testUtils.hpp | 4 +-- 217 files changed, 626 insertions(+), 624 deletions(-) diff --git a/doc/book/net.tex b/doc/book/net.tex index 361733ed..301e3f11 100644 --- a/doc/book/net.tex +++ b/doc/book/net.tex @@ -360,7 +360,7 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat const std::vector > getAcceptableMechanisms (const std::vector >& available, - vmime::shared_ptr suggested) const + const vmime::shared_ptr & suggested) const { // Here, you can sort the SASL mechanisms in the order they will be // tried. If no SASL mechanism is acceptable (ie. for example, not @@ -372,7 +372,7 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat getAcceptableMechanisms(available, suggested); } - void setSASLMechanism(vmime::shared_ptr mech) + void setSASLMechanism(const vmime::shared_ptr & mech) { // This is called when the authentication process is going to // try the specified mechanism. @@ -982,7 +982,7 @@ class myCertVerifier : public vmime::security::cert::certificateVerifier { public: - void verify(vmime::shared_ptr certs) + void verify(const vmime::shared_ptr & certs) { // Obtain the subject's certificate vmime::shared_ptr cert = chain->getAt(0); @@ -1130,7 +1130,7 @@ class myTracerFactory : public vmime::net::tracerFactory public: vmime::shared_ptr create - (vmime::shared_ptr serv, + (const vmime::shared_ptr & serv, const int connectionId) { return vmime::make_shared diff --git a/examples/example6_authenticator.hpp b/examples/example6_authenticator.hpp index b46f8ebd..64336e2a 100644 --- a/examples/example6_authenticator.hpp +++ b/examples/example6_authenticator.hpp @@ -7,7 +7,7 @@ class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthen { const std::vector > getAcceptableMechanisms (const std::vector >& available, - vmime::shared_ptr suggested) const + const vmime::shared_ptr & suggested) const { std::cout << std::endl << "Available SASL mechanisms:" << std::endl; @@ -24,7 +24,7 @@ class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthen return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested); } - void setSASLMechanism(vmime::shared_ptr mech) + void setSASLMechanism(const vmime::shared_ptr & mech) { std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl; diff --git a/examples/example6_certificateVerifier.hpp b/examples/example6_certificateVerifier.hpp index e98f7874..b4b47a2a 100644 --- a/examples/example6_certificateVerifier.hpp +++ b/examples/example6_certificateVerifier.hpp @@ -7,7 +7,7 @@ class interactiveCertificateVerifier : public vmime::security::cert::defaultCert { public: - void verify(vmime::shared_ptr chain, const vmime::string& hostname) + void verify(const vmime::shared_ptr & chain, const vmime::string& hostname) { try { diff --git a/examples/example6_tracer.hpp b/examples/example6_tracer.hpp index 19d0f040..8f57f56c 100644 --- a/examples/example6_tracer.hpp +++ b/examples/example6_tracer.hpp @@ -6,8 +6,8 @@ class myTracer : public vmime::net::tracer { public: - myTracer(vmime::shared_ptr stream, - vmime::shared_ptr serv, const int connectionId) + myTracer(const vmime::shared_ptr & stream, + const vmime::shared_ptr & serv, const int connectionId) : m_stream(stream), m_service(serv), m_connectionId(connectionId) { } @@ -35,13 +35,13 @@ class myTracerFactory : public vmime::net::tracerFactory { public: - myTracerFactory(vmime::shared_ptr stream) + myTracerFactory(const vmime::shared_ptr & stream) : m_stream(stream) { } vmime::shared_ptr create - (vmime::shared_ptr serv, const int connectionId) + (const vmime::shared_ptr & serv, const int connectionId) { return vmime::make_shared (m_stream, serv, connectionId); } diff --git a/src/vmime/addressList.cpp b/src/vmime/addressList.cpp index 5c7d34ac..23834f6f 100644 --- a/src/vmime/addressList.cpp +++ b/src/vmime/addressList.cpp @@ -139,13 +139,13 @@ shared_ptr addressList::clone() const } -void addressList::appendAddress(shared_ptr
addr) +void addressList::appendAddress(const shared_ptr
&addr) { m_list.push_back(addr); } -void addressList::insertAddressBefore(shared_ptr
beforeAddress, shared_ptr
addr) +void addressList::insertAddressBefore(const shared_ptr
& beforeAddress, const shared_ptr
& addr) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), beforeAddress); @@ -157,7 +157,7 @@ void addressList::insertAddressBefore(shared_ptr
beforeAddress, shared } -void addressList::insertAddressBefore(const size_t pos, shared_ptr
addr) +void addressList::insertAddressBefore(const size_t pos, const shared_ptr
& addr) { if (pos >= m_list.size()) throw std::out_of_range("Invalid position"); @@ -166,7 +166,7 @@ void addressList::insertAddressBefore(const size_t pos, shared_ptr
add } -void addressList::insertAddressAfter(shared_ptr
afterAddress, shared_ptr
addr) +void addressList::insertAddressAfter(const shared_ptr
& afterAddress, const shared_ptr
& addr) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), afterAddress); @@ -178,7 +178,7 @@ void addressList::insertAddressAfter(shared_ptr
afterAddress, shared_p } -void addressList::insertAddressAfter(const size_t pos, shared_ptr
addr) +void addressList::insertAddressAfter(const size_t pos, const shared_ptr
& addr) { if (pos >= m_list.size()) throw std::out_of_range("Invalid position"); @@ -187,7 +187,7 @@ void addressList::insertAddressAfter(const size_t pos, shared_ptr
addr } -void addressList::removeAddress(shared_ptr
addr) +void addressList::removeAddress(const shared_ptr
& addr) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), addr); diff --git a/src/vmime/addressList.hpp b/src/vmime/addressList.hpp index 0df657d3..c0909069 100644 --- a/src/vmime/addressList.hpp +++ b/src/vmime/addressList.hpp @@ -63,7 +63,7 @@ public: * * @param addr address to append */ - void appendAddress(shared_ptr
addr); + void appendAddress(const shared_ptr
& addr); /** Insert a new address before the specified address. * @@ -71,7 +71,7 @@ public: * @param addr address to insert * @throw std::out_of_range if the address is not in the list */ - void insertAddressBefore(shared_ptr
beforeAddress, shared_ptr
addr); + void insertAddressBefore(const shared_ptr
& beforeAddress, const shared_ptr
& addr); /** Insert a new address before the specified position. * @@ -80,7 +80,7 @@ public: * @param addr address to insert * @throw std::out_of_range if the position is out of range */ - void insertAddressBefore(const size_t pos, shared_ptr
addr); + void insertAddressBefore(const size_t pos, const shared_ptr
& addr); /** Insert a new address after the specified address. * @@ -88,7 +88,7 @@ public: * @param addr address to insert * @throw std::out_of_range if the address is not in the list */ - void insertAddressAfter(shared_ptr
afterAddress, shared_ptr
addr); + void insertAddressAfter(const shared_ptr
& afterAddress, const shared_ptr
& addr); /** Insert a new address after the specified position. * @@ -96,14 +96,14 @@ public: * @param addr address to insert * @throw std::out_of_range if the position is out of range */ - void insertAddressAfter(const size_t pos, shared_ptr
addr); + void insertAddressAfter(const size_t pos, const shared_ptr
& addr); /** Remove the specified address from the list. * * @param addr address to remove * @throw std::out_of_range if the address is not in the list */ - void removeAddress(shared_ptr
addr); + void removeAddress(const shared_ptr
& addr); /** Remove the address at the specified position. * diff --git a/src/vmime/attachment.hpp b/src/vmime/attachment.hpp index 9730bc6c..862e5d9e 100644 --- a/src/vmime/attachment.hpp +++ b/src/vmime/attachment.hpp @@ -108,7 +108,7 @@ protected: * * @param parent body part in which to generate the attachment */ - virtual void generateIn(shared_ptr parent) const = 0; + virtual void generateIn(const shared_ptr & parent) const = 0; }; diff --git a/src/vmime/attachmentHelper.cpp b/src/vmime/attachmentHelper.cpp index 152daeed..252a0377 100644 --- a/src/vmime/attachmentHelper.cpp +++ b/src/vmime/attachmentHelper.cpp @@ -39,7 +39,7 @@ namespace vmime // static bool attachmentHelper::isBodyPartAnAttachment - (shared_ptr part, const unsigned int options) + (const shared_ptr & part, const unsigned int options) { // First, try with "Content-Disposition" field. // If not present, we will try with "Content-Type" field. @@ -123,7 +123,7 @@ bool attachmentHelper::isBodyPartAnAttachment // static shared_ptr attachmentHelper::getBodyPartAttachment - (shared_ptr part, const unsigned int options) + (const shared_ptr & part, const unsigned int options) { if (!isBodyPartAnAttachment(part, options)) return null; @@ -159,7 +159,7 @@ shared_ptr attachmentHelper::getBodyPartAttachment // static const std::vector > attachmentHelper::findAttachmentsInMessage - (shared_ptr msg, const unsigned int options) + (const shared_ptr & msg, const unsigned int options) { return findAttachmentsInBodyPart(msg, options); } @@ -168,7 +168,7 @@ const std::vector > // static const std::vector > attachmentHelper::findAttachmentsInBodyPart - (shared_ptr part, const unsigned int options) + (const shared_ptr & part, const unsigned int options) { std::vector > atts; @@ -196,7 +196,7 @@ const std::vector > // static -void attachmentHelper::addAttachment(shared_ptr msg, shared_ptr att) +void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & att) { // We simply search for a "multipart/mixed" part. If no one exists, // create it in the root part. This (very simple) algorithm should @@ -279,7 +279,7 @@ void attachmentHelper::addAttachment(shared_ptr msg, shared_ptr attachmentHelper::findBodyPart - (shared_ptr part, const mediaType& type) + (const shared_ptr & part, const mediaType& type) { if (part->getBody()->getContentType() == type) return part; @@ -301,7 +301,7 @@ shared_ptr attachmentHelper::findBodyPart // static -void attachmentHelper::addAttachment(shared_ptr msg, shared_ptr amsg) +void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & amsg) { shared_ptr att = make_shared (amsg); addAttachment(msg, att); diff --git a/src/vmime/attachmentHelper.hpp b/src/vmime/attachmentHelper.hpp index e03a4f7d..f1588fe8 100644 --- a/src/vmime/attachmentHelper.hpp +++ b/src/vmime/attachmentHelper.hpp @@ -59,7 +59,7 @@ public: * @param options search options (see FindOptions) * @return true if the part is an attachment, false otherwise */ - static bool isBodyPartAnAttachment(shared_ptr part, const unsigned int options = 0); + static bool isBodyPartAnAttachment(const shared_ptr & part, const unsigned int options = 0); /** Return attachment information in the specified body part. * If the specified body part does not contain attachment @@ -70,7 +70,7 @@ public: * @return attachment found in the part, or NULL */ static shared_ptr - getBodyPartAttachment(shared_ptr part, const unsigned int options = 0); + getBodyPartAttachment(const shared_ptr & part, const unsigned int options = 0); /** Find all attachments contained in the specified part * and all its children parts. @@ -81,7 +81,7 @@ public: * @return a list of attachments found */ static const std::vector > - findAttachmentsInBodyPart(shared_ptr part, const unsigned int options = 0); + findAttachmentsInBodyPart(const shared_ptr & part, const unsigned int options = 0); /** Find all attachments contained in the specified message. * This is simply a recursive call to getBodyPartAttachment(). @@ -91,26 +91,26 @@ public: * @return a list of attachments found */ static const std::vector > - findAttachmentsInMessage(shared_ptr msg, const unsigned int options = 0); + findAttachmentsInMessage(const shared_ptr & msg, const unsigned int options = 0); /** Add an attachment to the specified message. * * @param msg message into which to add the attachment * @param att attachment to add */ - static void addAttachment(shared_ptr msg, shared_ptr att); + static void addAttachment(const shared_ptr & msg, const shared_ptr & att); /** Add a message attachment to the specified message. * * @param msg message into which to add the attachment * @param amsg message to attach */ - static void addAttachment(shared_ptr msg, shared_ptr amsg); + static void addAttachment(const shared_ptr & msg, const shared_ptr & amsg); protected: static shared_ptr findBodyPart - (shared_ptr part, const mediaType& type); + (const shared_ptr & part, const mediaType& type); }; diff --git a/src/vmime/base.hpp b/src/vmime/base.hpp index f6515794..b39ff55e 100644 --- a/src/vmime/base.hpp +++ b/src/vmime/base.hpp @@ -192,7 +192,7 @@ namespace vmime * This is an alias for dynamic_pointer_cast (obj->clone()). */ template - shared_ptr clone(shared_ptr obj) + shared_ptr clone(const shared_ptr & obj) { return dynamic_pointer_cast (obj->clone()); } @@ -201,7 +201,7 @@ namespace vmime * This is an alias for dynamic_pointer_cast (obj->clone()). */ template - shared_ptr clone(shared_ptr obj) + shared_ptr clone(const shared_ptr & obj) { return dynamic_pointer_cast (obj->clone()); } @@ -220,7 +220,7 @@ namespace vmime * type Type, and DerivedType is derived from Type. */ template - shared_ptr dynamicCast(shared_ptr obj) + shared_ptr dynamicCast(const shared_ptr & obj) { return dynamic_pointer_cast (obj); } diff --git a/src/vmime/body.cpp b/src/vmime/body.cpp index e5813375..41624b7b 100644 --- a/src/vmime/body.cpp +++ b/src/vmime/body.cpp @@ -56,7 +56,7 @@ body::~body() // static size_t body::findNextBoundaryPosition - (shared_ptr parser, const string& boundary, + (const shared_ptr & parser, const string& boundary, const size_t position, const size_t end, size_t* boundaryStart, size_t* boundaryEnd) { @@ -129,7 +129,7 @@ size_t body::findNextBoundaryPosition void body::parseImpl (const parsingContext& ctx, - shared_ptr parser, + const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition) { removeAllParts(); @@ -839,13 +839,13 @@ const shared_ptr body::getContents() const } -void body::setContents(shared_ptr contents) +void body::setContents(const shared_ptr & contents) { m_contents = contents; } -void body::setContents(shared_ptr contents, const mediaType& type) +void body::setContents(const shared_ptr & contents, const mediaType& type) { m_contents = contents; @@ -853,7 +853,7 @@ void body::setContents(shared_ptr contents, const mediaTy } -void body::setContents(shared_ptr contents, const mediaType& type, const charset& chset) +void body::setContents(const shared_ptr & contents, const mediaType& type, const charset& chset) { m_contents = contents; @@ -861,7 +861,7 @@ void body::setContents(shared_ptr contents, const mediaTy } -void body::setContents(shared_ptr contents, const mediaType& type, +void body::setContents(const shared_ptr & contents, const mediaType& type, const charset& chset, const encoding& enc) { m_contents = contents; @@ -871,7 +871,7 @@ void body::setContents(shared_ptr contents, const mediaTy } -void body::initNewPart(shared_ptr part) +void body::initNewPart(const shared_ptr & part) { // A part can be in only one body at the same time: if part is // already attached to a parent part, remove it from the current @@ -923,7 +923,7 @@ void body::initNewPart(shared_ptr part) } -void body::appendPart(shared_ptr part) +void body::appendPart(const shared_ptr & part) { initNewPart(part); @@ -931,7 +931,7 @@ void body::appendPart(shared_ptr part) } -void body::insertPartBefore(shared_ptr beforePart, shared_ptr part) +void body::insertPartBefore(const shared_ptr & beforePart, const shared_ptr & part) { initNewPart(part); @@ -945,7 +945,7 @@ void body::insertPartBefore(shared_ptr beforePart, shared_ptr part) +void body::insertPartBefore(const size_t pos, const shared_ptr & part) { initNewPart(part); @@ -953,7 +953,7 @@ void body::insertPartBefore(const size_t pos, shared_ptr part) } -void body::insertPartAfter(shared_ptr afterPart, shared_ptr part) +void body::insertPartAfter(const shared_ptr & afterPart, const shared_ptr & part) { initNewPart(part); @@ -967,7 +967,7 @@ void body::insertPartAfter(shared_ptr afterPart, shared_ptr part) +void body::insertPartAfter(const size_t pos, const shared_ptr & part) { initNewPart(part); @@ -975,7 +975,7 @@ void body::insertPartAfter(const size_t pos, shared_ptr part) } -void body::removePart(shared_ptr part) +void body::removePart(const shared_ptr & part) { const std::vector >::iterator it = std::find (m_parts.begin(), m_parts.end(), part); diff --git a/src/vmime/body.hpp b/src/vmime/body.hpp index e47f97e9..24f010b4 100644 --- a/src/vmime/body.hpp +++ b/src/vmime/body.hpp @@ -60,7 +60,7 @@ public: * * @param part part to append */ - void appendPart(shared_ptr part); + void appendPart(const shared_ptr & part); /** Insert a new part before the specified part. * @@ -68,7 +68,7 @@ public: * @param part part to insert * @throw exceptions::no_such_part if the part is not in the list */ - void insertPartBefore(shared_ptr beforePart, shared_ptr part); + void insertPartBefore(const shared_ptr & beforePart, const shared_ptr & part); /** Insert a new part before the specified position. * @@ -76,7 +76,7 @@ public: * the beginning of the list) * @param part part to insert */ - void insertPartBefore(const size_t pos, shared_ptr part); + void insertPartBefore(const size_t pos, const shared_ptr & part); /** Insert a new part after the specified part. * @@ -84,21 +84,21 @@ public: * @param part part to insert * @throw exceptions::no_such_part if the part is not in the list */ - void insertPartAfter(shared_ptr afterPart, shared_ptr part); + void insertPartAfter(const shared_ptr & afterPart, const shared_ptr & part); /** Insert a new part after the specified position. * * @param pos position of the part before the new part * @param part part to insert */ - void insertPartAfter(const size_t pos, shared_ptr part); + void insertPartAfter(const size_t pos, const shared_ptr & part); /** Remove the specified part from the list. * * @param part part to remove * @throw exceptions::no_such_part if the part is not in the list */ - void removePart(shared_ptr part); + void removePart(const shared_ptr & part); /** Remove the part at the specified position. * @@ -182,14 +182,14 @@ public: * * @param contents new body contents */ - void setContents(shared_ptr contents); + void setContents(const shared_ptr & contents); /** Set the body contents and type. * * @param contents new body contents * @param type type of contents */ - void setContents(shared_ptr contents, const mediaType& type); + void setContents(const shared_ptr & contents, const mediaType& type); /** Set the body contents, type and charset. * @@ -197,7 +197,7 @@ public: * @param type type of contents * @param chset charset of contents */ - void setContents(shared_ptr contents, const mediaType& type, const charset& chset); + void setContents(const shared_ptr & contents, const mediaType& type, const charset& chset); /** Set the body contents, type, charset and encoding. * @@ -206,7 +206,7 @@ public: * @param chset charset of contents * @param enc contents encoding */ - void setContents(shared_ptr contents, const mediaType& type, + void setContents(const shared_ptr & contents, const mediaType& type, const charset& chset, const encoding& enc); /** Set the MIME type and charset of contents. @@ -301,7 +301,7 @@ private: bool isRootPart() const; - void initNewPart(shared_ptr part); + void initNewPart(const shared_ptr & part); protected: @@ -318,14 +318,14 @@ protected: * @return the position of the boundary string, or npos if not found */ size_t findNextBoundaryPosition - (shared_ptr parser, const string& boundary, + (const shared_ptr & parser, const string& boundary, const size_t position, const size_t end, size_t* boundaryStart, size_t* boundaryEnd); // Component parsing & assembling void parseImpl (const parsingContext& ctx, - shared_ptr parser, + const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition = NULL); diff --git a/src/vmime/bodyPart.cpp b/src/vmime/bodyPart.cpp index 12896f84..c215eb80 100644 --- a/src/vmime/bodyPart.cpp +++ b/src/vmime/bodyPart.cpp @@ -38,7 +38,7 @@ bodyPart::bodyPart() void bodyPart::parseImpl - (const parsingContext& ctx, shared_ptr parser, + (const parsingContext& ctx, const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition) { // Parse the headers @@ -117,7 +117,7 @@ shared_ptr
bodyPart::getHeader() } -void bodyPart::setHeader(shared_ptr
h) +void bodyPart::setHeader(const shared_ptr
& h) { m_header = h; } @@ -135,7 +135,7 @@ shared_ptr bodyPart::getBody() } -void bodyPart::setBody(shared_ptr b) +void bodyPart::setBody(const shared_ptr & b) { bodyPart* oldPart = b->m_part; @@ -169,7 +169,7 @@ shared_ptr bodyPart::createChildPart() } -void bodyPart::importChildPart(shared_ptr part) +void bodyPart::importChildPart(const shared_ptr & part) { part->m_parent = this; } diff --git a/src/vmime/bodyPart.hpp b/src/vmime/bodyPart.hpp index 214cb208..729af253 100644 --- a/src/vmime/bodyPart.hpp +++ b/src/vmime/bodyPart.hpp @@ -63,7 +63,7 @@ public: * * @param header the new header of this part */ - void setHeader(shared_ptr
header); + void setHeader(const shared_ptr
& header); /** Return the body section of this part. * @@ -81,7 +81,7 @@ public: * * @param body new body section */ - void setBody(shared_ptr body); + void setBody(const shared_ptr & body); /** Return the parent part of this part. * @@ -131,12 +131,12 @@ protected: * * @param part child part to attach */ - void importChildPart(shared_ptr part); + void importChildPart(const shared_ptr & part); // Component parsing & assembling void parseImpl (const parsingContext& ctx, - shared_ptr parser, + const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition = NULL); diff --git a/src/vmime/bodyPartAttachment.cpp b/src/vmime/bodyPartAttachment.cpp index 0684a896..07a92d12 100644 --- a/src/vmime/bodyPartAttachment.cpp +++ b/src/vmime/bodyPartAttachment.cpp @@ -28,7 +28,7 @@ namespace vmime { -bodyPartAttachment::bodyPartAttachment(shared_ptr part) +bodyPartAttachment::bodyPartAttachment(const shared_ptr & part) : m_part(part) { } @@ -136,7 +136,7 @@ shared_ptr bodyPartAttachment::getContentType() const } -void bodyPartAttachment::generateIn(shared_ptr /* parent */) const +void bodyPartAttachment::generateIn(const shared_ptr & /* parent */) const { // Not used } diff --git a/src/vmime/bodyPartAttachment.hpp b/src/vmime/bodyPartAttachment.hpp index e1a4a89a..43848bd3 100644 --- a/src/vmime/bodyPartAttachment.hpp +++ b/src/vmime/bodyPartAttachment.hpp @@ -44,7 +44,7 @@ class VMIME_EXPORT bodyPartAttachment : public attachment { public: - bodyPartAttachment(shared_ptr part); + bodyPartAttachment(const shared_ptr & part); const mediaType getType() const; const word getName() const; @@ -58,7 +58,7 @@ public: private: - void generateIn(shared_ptr parent) const; + void generateIn(const shared_ptr & parent) const; shared_ptr getContentDisposition() const; shared_ptr getContentType() const; diff --git a/src/vmime/component.cpp b/src/vmime/component.cpp index 46ff4036..342d087b 100644 --- a/src/vmime/component.cpp +++ b/src/vmime/component.cpp @@ -47,14 +47,14 @@ component::~component() void component::parse - (shared_ptr inputStream, const size_t length) + (const shared_ptr & inputStream, const size_t length) { parse(inputStream, 0, length, NULL); } void component::parse - (shared_ptr inputStream, const size_t position, + (const shared_ptr & inputStream, const size_t position, const size_t end, size_t* newPosition) { parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition); @@ -63,7 +63,7 @@ void component::parse void component::parse (const parsingContext& ctx, - shared_ptr inputStream, const size_t position, + const shared_ptr & inputStream, const size_t position, const size_t end, size_t* newPosition) { m_parsedOffset = m_parsedLength = 0; @@ -144,7 +144,7 @@ void component::offsetParsedBounds(const size_t offset) void component::parseImpl - (const parsingContext& ctx, shared_ptr parser, + (const parsingContext& ctx, const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition) { // This is the default implementation for parsing from an input stream: diff --git a/src/vmime/component.hpp b/src/vmime/component.hpp index 87d465e8..6c360746 100644 --- a/src/vmime/component.hpp +++ b/src/vmime/component.hpp @@ -70,7 +70,7 @@ public: * @param inputStream stream from which to read data * @param length data length, in bytes (0 = unknown/not specified) */ - void parse(shared_ptr inputStream, const size_t length); + void parse(const shared_ptr & inputStream, const size_t length); /** Parse RFC-822/MIME data for this component, using the default * parsing context. @@ -112,7 +112,7 @@ public: * @param newPosition will receive the new position in the input stream */ void parse - (shared_ptr inputStream, + (const shared_ptr & inputStream, const size_t position, const size_t end, size_t* newPosition = NULL); @@ -129,7 +129,7 @@ public: */ void parse (const parsingContext& ctx, - shared_ptr inputStream, + const shared_ptr & inputStream, const size_t position, const size_t end, size_t* newPosition = NULL); @@ -224,7 +224,7 @@ protected: // AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class virtual void parseImpl (const parsingContext& ctx, - shared_ptr parser, + const shared_ptr & parser, const size_t position, const size_t end, size_t* newPosition = NULL); diff --git a/src/vmime/defaultAttachment.cpp b/src/vmime/defaultAttachment.cpp index 8f8ad453..2eb9289a 100644 --- a/src/vmime/defaultAttachment.cpp +++ b/src/vmime/defaultAttachment.cpp @@ -37,14 +37,14 @@ defaultAttachment::defaultAttachment() } -defaultAttachment::defaultAttachment(shared_ptr data, +defaultAttachment::defaultAttachment(const shared_ptr & data, const encoding& enc, const mediaType& type, const text& desc, const word& name) : m_type(type), m_desc(desc), m_data(data), m_encoding(enc), m_name(name) { } -defaultAttachment::defaultAttachment(shared_ptr data, +defaultAttachment::defaultAttachment(const shared_ptr & data, const mediaType& type, const text& desc, const word& name) : m_type(type), m_desc(desc), m_data(data), m_encoding(encoding::decide(data)), m_name(name) @@ -77,7 +77,7 @@ defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach) } -void defaultAttachment::generateIn(shared_ptr parent) const +void defaultAttachment::generateIn(const shared_ptr & parent) const { // Create and append a new part for this attachment shared_ptr part = make_shared (); @@ -87,7 +87,7 @@ void defaultAttachment::generateIn(shared_ptr parent) const } -void defaultAttachment::generatePart(shared_ptr part) const +void defaultAttachment::generatePart(const shared_ptr & part) const { // Set header fields part->getHeader()->ContentType()->setValue(m_type); diff --git a/src/vmime/defaultAttachment.hpp b/src/vmime/defaultAttachment.hpp index 6eb0c5b6..817e834b 100644 --- a/src/vmime/defaultAttachment.hpp +++ b/src/vmime/defaultAttachment.hpp @@ -45,8 +45,8 @@ protected: public: - defaultAttachment(shared_ptr data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); - defaultAttachment(shared_ptr data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); + defaultAttachment(const shared_ptr & data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); + defaultAttachment(const shared_ptr & data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); defaultAttachment(const defaultAttachment& attach); ~defaultAttachment(); @@ -74,11 +74,11 @@ protected: private: // No need to override "generateIn", use "generatePart" instead (see below). - void generateIn(shared_ptr parent) const; + void generateIn(const shared_ptr & parent) const; protected: - virtual void generatePart(shared_ptr part) const; + virtual void generatePart(const shared_ptr & part) const; }; diff --git a/src/vmime/encoding.cpp b/src/vmime/encoding.cpp index 26922395..649bee79 100644 --- a/src/vmime/encoding.cpp +++ b/src/vmime/encoding.cpp @@ -200,7 +200,7 @@ bool encoding::shouldReencode() const const encoding encoding::decide - (shared_ptr data, const EncodingUsage usage) + (const shared_ptr & data, const EncodingUsage usage) { // Do not re-encode data if it is already encoded if (data->isEncoded() && !data->getEncoding().shouldReencode()) @@ -231,7 +231,7 @@ const encoding encoding::decide } -const encoding encoding::decide(shared_ptr data, +const encoding encoding::decide(const shared_ptr & data, const charset& chset, const EncodingUsage usage) { // Do not re-encode data if it is already encoded diff --git a/src/vmime/encoding.hpp b/src/vmime/encoding.hpp index 90733807..48973daa 100644 --- a/src/vmime/encoding.hpp +++ b/src/vmime/encoding.hpp @@ -99,7 +99,7 @@ public: * @param usage context of use of data * @return suitable encoding for specified data */ - static const encoding decide(shared_ptr data, const EncodingUsage usage = USAGE_BINARY_DATA); + static const encoding decide(const shared_ptr & data, const EncodingUsage usage = USAGE_BINARY_DATA); /** Decide which encoding to use based on the specified data and charset. * @@ -108,7 +108,7 @@ public: * @param usage context of use of data * @return suitable encoding for specified data and charset */ - static const encoding decide(shared_ptr data, const charset& chset, const EncodingUsage usage = USAGE_BINARY_DATA); + static const encoding decide(const shared_ptr & data, const charset& chset, const EncodingUsage usage = USAGE_BINARY_DATA); shared_ptr clone() const; diff --git a/src/vmime/fileAttachment.cpp b/src/vmime/fileAttachment.cpp index 25a97fcc..f1697519 100644 --- a/src/vmime/fileAttachment.cpp +++ b/src/vmime/fileAttachment.cpp @@ -79,7 +79,7 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type, } -fileAttachment::fileAttachment(shared_ptr cts, const word& filename, const mediaType& type) +fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type) { if (!filename.isEmpty()) m_fileInfo.setFilename(filename); @@ -92,7 +92,7 @@ fileAttachment::fileAttachment(shared_ptr cts, const word& file } -fileAttachment::fileAttachment(shared_ptr cts, const word& filename, +fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc) { if (!filename.isEmpty()) @@ -107,7 +107,7 @@ fileAttachment::fileAttachment(shared_ptr cts, const word& file } -fileAttachment::fileAttachment(shared_ptr cts, const word& filename, +fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc) { if (!filename.isEmpty()) @@ -139,7 +139,7 @@ void fileAttachment::setData(const string& filepath) } -void fileAttachment::setData(shared_ptr cts) +void fileAttachment::setData(const shared_ptr & cts) { m_data = cts; @@ -147,7 +147,7 @@ void fileAttachment::setData(shared_ptr cts) } -void fileAttachment::generatePart(shared_ptr part) const +void fileAttachment::generatePart(const shared_ptr & part) const { defaultAttachment::generatePart(part); diff --git a/src/vmime/fileAttachment.hpp b/src/vmime/fileAttachment.hpp index 3c6ca398..03e3e283 100644 --- a/src/vmime/fileAttachment.hpp +++ b/src/vmime/fileAttachment.hpp @@ -52,9 +52,9 @@ public: fileAttachment(const string& filepath, const mediaType& type, const text& desc); fileAttachment(const string& filepath, const mediaType& type, const text& desc, const encoding& enc); - fileAttachment(shared_ptr cts, const word& filename, const mediaType& type); - fileAttachment(shared_ptr cts, const word& filename, const mediaType& type, const text& desc); - fileAttachment(shared_ptr cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc); + fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type); + fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc); + fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc); /** Stores information about a file attachment. */ @@ -181,11 +181,11 @@ public: private: void setData(const string& filepath); - void setData(shared_ptr cts); + void setData(const shared_ptr & cts); fileInfo m_fileInfo; - void generatePart(shared_ptr part) const; + void generatePart(const shared_ptr & part) const; }; diff --git a/src/vmime/fileContentHandler.cpp b/src/vmime/fileContentHandler.cpp index df788d7d..531151b4 100644 --- a/src/vmime/fileContentHandler.cpp +++ b/src/vmime/fileContentHandler.cpp @@ -41,7 +41,7 @@ fileContentHandler::fileContentHandler() fileContentHandler::fileContentHandler - (shared_ptr file, const vmime::encoding& enc) + (const shared_ptr & file, const vmime::encoding& enc) { setData(file, enc); } @@ -74,7 +74,7 @@ shared_ptr fileContentHandler::clone() const void fileContentHandler::setData - (shared_ptr file, const vmime::encoding& enc) + (const shared_ptr & file, const vmime::encoding& enc) { m_file = file; m_encoding = enc; diff --git a/src/vmime/fileContentHandler.hpp b/src/vmime/fileContentHandler.hpp index 5b01fb8b..1436a002 100644 --- a/src/vmime/fileContentHandler.hpp +++ b/src/vmime/fileContentHandler.hpp @@ -62,7 +62,7 @@ public: * @return a reference to a new content handler */ fileContentHandler - (shared_ptr file, + (const shared_ptr & file, const vmime::encoding& enc = NO_ENCODING); ~fileContentHandler(); @@ -79,7 +79,7 @@ public: * in the file is already encoded with the specified encoding */ void setData - (shared_ptr file, + (const shared_ptr & file, const vmime::encoding& enc = NO_ENCODING); private: diff --git a/src/vmime/generatedMessageAttachment.cpp b/src/vmime/generatedMessageAttachment.cpp index 0473d247..b58b56d8 100644 --- a/src/vmime/generatedMessageAttachment.cpp +++ b/src/vmime/generatedMessageAttachment.cpp @@ -30,7 +30,7 @@ namespace vmime { -generatedMessageAttachment::generatedMessageAttachment(shared_ptr part) +generatedMessageAttachment::generatedMessageAttachment(const shared_ptr & part) : m_bpa(make_shared (part)) { } @@ -97,7 +97,7 @@ shared_ptr generatedMessageAttachment::getMessage() const } -void generatedMessageAttachment::generateIn(shared_ptr /* parent */) const +void generatedMessageAttachment::generateIn(const shared_ptr & /* parent */) const { // Not used (see 'parsedMessageAttachment') } diff --git a/src/vmime/generatedMessageAttachment.hpp b/src/vmime/generatedMessageAttachment.hpp index 7137b22b..e1e00cc7 100644 --- a/src/vmime/generatedMessageAttachment.hpp +++ b/src/vmime/generatedMessageAttachment.hpp @@ -42,7 +42,7 @@ class VMIME_EXPORT generatedMessageAttachment : public messageAttachment { public: - generatedMessageAttachment(shared_ptr part); + generatedMessageAttachment(const shared_ptr & part); const mediaType getType() const; const text getDescription() const; @@ -60,7 +60,7 @@ public: protected: - void generateIn(shared_ptr parent) const; + void generateIn(const shared_ptr & parent) const; private: diff --git a/src/vmime/header.cpp b/src/vmime/header.cpp index 34b5fa6e..cd2a6f7e 100644 --- a/src/vmime/header.cpp +++ b/src/vmime/header.cpp @@ -219,13 +219,13 @@ shared_ptr header::getField(const string& fieldName) } -void header::appendField(shared_ptr field) +void header::appendField(const shared_ptr & field) { m_fields.push_back(field); } -void header::insertFieldBefore(shared_ptr beforeField, shared_ptr field) +void header::insertFieldBefore(const shared_ptr & beforeField, const shared_ptr & field) { const std::vector >::iterator it = std::find (m_fields.begin(), m_fields.end(), beforeField); @@ -237,13 +237,13 @@ void header::insertFieldBefore(shared_ptr beforeField, shared_ptr } -void header::insertFieldBefore(const size_t pos, shared_ptr field) +void header::insertFieldBefore(const size_t pos, const shared_ptr & field) { m_fields.insert(m_fields.begin() + pos, field); } -void header::insertFieldAfter(shared_ptr afterField, shared_ptr field) +void header::insertFieldAfter(const shared_ptr & afterField, const shared_ptr & field) { const std::vector >::iterator it = std::find (m_fields.begin(), m_fields.end(), afterField); @@ -255,13 +255,13 @@ void header::insertFieldAfter(shared_ptr afterField, shared_ptr field) +void header::insertFieldAfter(const size_t pos, const shared_ptr & field) { m_fields.insert(m_fields.begin() + pos + 1, field); } -void header::removeField(shared_ptr field) +void header::removeField(const shared_ptr & field) { const std::vector >::iterator it = std::find (m_fields.begin(), m_fields.end(), field); @@ -281,7 +281,7 @@ void header::removeField(const size_t pos) } -void header::replaceField(shared_ptr field, shared_ptr newField) +void header::replaceField(const shared_ptr & field, const shared_ptr & newField) { insertFieldBefore(field, newField); removeField(field); diff --git a/src/vmime/header.hpp b/src/vmime/header.hpp index d2d20727..f2fd0666 100644 --- a/src/vmime/header.hpp +++ b/src/vmime/header.hpp @@ -185,7 +185,7 @@ public: * * @param field field to append */ - void appendField(shared_ptr field); + void appendField(const shared_ptr & field); /** Insert a new field before the specified field. * @@ -193,7 +193,7 @@ public: * @param field field to insert * @throw exceptions::no_such_field if the field is not in the list */ - void insertFieldBefore(shared_ptr beforeField, shared_ptr field); + void insertFieldBefore(const shared_ptr & beforeField, const shared_ptr & field); /** Insert a new field before the specified position. * @@ -201,7 +201,7 @@ public: * the beginning of the list) * @param field field to insert */ - void insertFieldBefore(const size_t pos, shared_ptr field); + void insertFieldBefore(const size_t pos, const shared_ptr & field); /** Insert a new field after the specified field. * @@ -209,21 +209,21 @@ public: * @param field field to insert * @throw exceptions::no_such_field if the field is not in the list */ - void insertFieldAfter(shared_ptr afterField, shared_ptr field); + void insertFieldAfter(const shared_ptr & afterField, const shared_ptr & field); /** Insert a new field after the specified position. * * @param pos position of the field before the new field * @param field field to insert */ - void insertFieldAfter(const size_t pos, shared_ptr field); + void insertFieldAfter(const size_t pos, const shared_ptr & field); /** Remove the specified field from the list. * * @param field field to remove * @throw exceptions::no_such_field if the field is not in the list */ - void removeField(shared_ptr field); + void removeField(const shared_ptr & field); /** Remove the field at the specified position. * @@ -237,7 +237,7 @@ public: * @param newField field to replace with * @throw exceptions::no_such_field if the field is not in the list */ - void replaceField(shared_ptr field, shared_ptr newField); + void replaceField(const shared_ptr & field, const shared_ptr & newField); /** Remove all fields from the list. */ diff --git a/src/vmime/headerField.cpp b/src/vmime/headerField.cpp index 40611a45..05f5b046 100644 --- a/src/vmime/headerField.cpp +++ b/src/vmime/headerField.cpp @@ -300,7 +300,7 @@ shared_ptr headerField::getValue() } -void headerField::setValue(shared_ptr value) +void headerField::setValue(const shared_ptr & value) { if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) throw exceptions::bad_field_value_type(getName()); @@ -310,7 +310,7 @@ void headerField::setValue(shared_ptr value) } -void headerField::setValueConst(shared_ptr value) +void headerField::setValueConst(const shared_ptr & value) { if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) throw exceptions::bad_field_value_type(getName()); diff --git a/src/vmime/headerField.hpp b/src/vmime/headerField.hpp index 555805db..9c49235c 100644 --- a/src/vmime/headerField.hpp +++ b/src/vmime/headerField.hpp @@ -118,7 +118,7 @@ public: * valid for this header field * @param value new value */ - virtual void setValue(shared_ptr value); + virtual void setValue(const shared_ptr & value); /** Set the value of this field by cloning the specified value. * @@ -126,7 +126,7 @@ public: * valid for this header field * @param value new value */ - virtual void setValueConst(shared_ptr value); + virtual void setValueConst(const shared_ptr & value); /** Set the value of this field (reference version). * The value will be cloned. diff --git a/src/vmime/htmlTextPart.cpp b/src/vmime/htmlTextPart.cpp index cd7d6204..bda33cc0 100644 --- a/src/vmime/htmlTextPart.cpp +++ b/src/vmime/htmlTextPart.cpp @@ -62,7 +62,7 @@ size_t htmlTextPart::getPartCount() const } -void htmlTextPart::generateIn(shared_ptr /* message */, shared_ptr parent) const +void htmlTextPart::generateIn(const shared_ptr & /* message */, const shared_ptr & parent) const { // Plain text if (!m_plainText->isEmpty()) @@ -182,7 +182,7 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id, } -void htmlTextPart::parse(shared_ptr message, shared_ptr parent, shared_ptr textPart) +void htmlTextPart::parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart) { // Search for possible embedded objects in the _whole_ message. std::vector > cidParts; @@ -348,7 +348,7 @@ shared_ptr htmlTextPart::getPlainText() const } -void htmlTextPart::setPlainText(shared_ptr plainText) +void htmlTextPart::setPlainText(const shared_ptr & plainText) { m_plainText = plainText->clone(); } @@ -360,7 +360,7 @@ const shared_ptr htmlTextPart::getText() const } -void htmlTextPart::setText(shared_ptr text) +void htmlTextPart::setText(const shared_ptr & text) { m_text = text->clone(); } @@ -405,7 +405,7 @@ bool htmlTextPart::hasObject(const string& id) const shared_ptr htmlTextPart::addObject - (shared_ptr data, const vmime::encoding& enc, const mediaType& type) + (const shared_ptr & data, const vmime::encoding& enc, const mediaType& type) { const messageId mid(messageId::generateId()); @@ -419,7 +419,7 @@ shared_ptr htmlTextPart::addObject shared_ptr htmlTextPart::addObject - (shared_ptr data, const mediaType& type) + (const shared_ptr & data, const mediaType& type) { return addObject(data, encoding::decide(data), type); } @@ -439,7 +439,7 @@ shared_ptr htmlTextPart::addObject // htmlTextPart::embeddedObject::embeddedObject - (shared_ptr data, const encoding& enc, + (const shared_ptr & data, const encoding& enc, const string& id, const mediaType& type, const ReferenceType refType) : m_data(vmime::clone(data)), m_encoding(enc), m_id(id), m_type(type), m_refType(refType) diff --git a/src/vmime/htmlTextPart.hpp b/src/vmime/htmlTextPart.hpp index a7fe6aab..5ccdf4fa 100644 --- a/src/vmime/htmlTextPart.hpp +++ b/src/vmime/htmlTextPart.hpp @@ -52,10 +52,10 @@ public: void setCharset(const charset& ch); shared_ptr getPlainText() const; - void setPlainText(shared_ptr plainText); + void setPlainText(const shared_ptr & plainText); const shared_ptr getText() const; - void setText(shared_ptr text); + void setText(const shared_ptr & text); /** Embedded object (eg: image for <IMG> tag). */ @@ -79,7 +79,7 @@ public: * @param refType reference type * @return a reference to a new embedded object */ - embeddedObject(shared_ptr data, const encoding& enc, + embeddedObject(const shared_ptr & data, const encoding& enc, const string& id, const mediaType& type, const ReferenceType refType); @@ -196,7 +196,7 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - shared_ptr addObject(shared_ptr data, const mediaType& type); + shared_ptr addObject(const shared_ptr & data, const mediaType& type); /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -208,13 +208,13 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - shared_ptr addObject(shared_ptr data, const encoding& enc, const mediaType& type); + shared_ptr addObject(const shared_ptr & data, const encoding& enc, const mediaType& type); size_t getPartCount() const; - void generateIn(shared_ptr message, shared_ptr parent) const; - void parse(shared_ptr message, shared_ptr parent, shared_ptr textPart); + void generateIn(const shared_ptr & message, const shared_ptr & parent) const; + void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart); private: diff --git a/src/vmime/mailboxGroup.cpp b/src/vmime/mailboxGroup.cpp index 5e8d6b1b..99ca8282 100644 --- a/src/vmime/mailboxGroup.cpp +++ b/src/vmime/mailboxGroup.cpp @@ -246,13 +246,13 @@ bool mailboxGroup::isEmpty() const } -void mailboxGroup::appendMailbox(shared_ptr mbox) +void mailboxGroup::appendMailbox(const shared_ptr & mbox) { m_list.push_back(mbox); } -void mailboxGroup::insertMailboxBefore(shared_ptr beforeMailbox, shared_ptr mbox) +void mailboxGroup::insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), beforeMailbox); @@ -264,7 +264,7 @@ void mailboxGroup::insertMailboxBefore(shared_ptr beforeMailbox, share } -void mailboxGroup::insertMailboxBefore(const size_t pos, shared_ptr mbox) +void mailboxGroup::insertMailboxBefore(const size_t pos, const shared_ptr & mbox) { if (pos >= m_list.size()) throw std::out_of_range("Invalid position"); @@ -273,7 +273,7 @@ void mailboxGroup::insertMailboxBefore(const size_t pos, shared_ptr mb } -void mailboxGroup::insertMailboxAfter(shared_ptr afterMailbox, shared_ptr mbox) +void mailboxGroup::insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), afterMailbox); @@ -285,7 +285,7 @@ void mailboxGroup::insertMailboxAfter(shared_ptr afterMailbox, shared_ } -void mailboxGroup::insertMailboxAfter(const size_t pos, shared_ptr mbox) +void mailboxGroup::insertMailboxAfter(const size_t pos, const shared_ptr & mbox) { if (pos >= m_list.size()) throw std::out_of_range("Invalid position"); @@ -294,7 +294,7 @@ void mailboxGroup::insertMailboxAfter(const size_t pos, shared_ptr mbo } -void mailboxGroup::removeMailbox(shared_ptr mbox) +void mailboxGroup::removeMailbox(const shared_ptr & mbox) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), mbox); diff --git a/src/vmime/mailboxGroup.hpp b/src/vmime/mailboxGroup.hpp index b264cf60..7ae8fd9a 100644 --- a/src/vmime/mailboxGroup.hpp +++ b/src/vmime/mailboxGroup.hpp @@ -70,7 +70,7 @@ public: * * @param mbox mailbox to append */ - void appendMailbox(shared_ptr mbox); + void appendMailbox(const shared_ptr & mbox); /** Insert a new mailbox before the specified mailbox. * @@ -78,7 +78,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxBefore(shared_ptr beforeMailbox, shared_ptr mbox); + void insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox); /** Insert a new mailbox before the specified position. * @@ -87,7 +87,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxBefore(const size_t pos, shared_ptr mbox); + void insertMailboxBefore(const size_t pos, const shared_ptr & mbox); /** Insert a new mailbox after the specified mailbox. * @@ -95,7 +95,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxAfter(shared_ptr afterMailbox, shared_ptr mbox); + void insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox); /** Insert a new mailbox after the specified position. * @@ -103,14 +103,14 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxAfter(const size_t pos, shared_ptr mbox); + void insertMailboxAfter(const size_t pos, const shared_ptr & mbox); /** Remove the specified mailbox from the list. * * @param mbox mailbox to remove * @throw std::out_of_range if the mailbox is not in the list */ - void removeMailbox(shared_ptr mbox); + void removeMailbox(const shared_ptr & mbox); /** Remove the mailbox at the specified position. * diff --git a/src/vmime/mailboxList.cpp b/src/vmime/mailboxList.cpp index b356a1e7..bc99818b 100644 --- a/src/vmime/mailboxList.cpp +++ b/src/vmime/mailboxList.cpp @@ -41,37 +41,37 @@ mailboxList::mailboxList(const mailboxList& mboxList) } -void mailboxList::appendMailbox(shared_ptr mbox) +void mailboxList::appendMailbox(const shared_ptr & mbox) { m_list.appendAddress(mbox); } -void mailboxList::insertMailboxBefore(shared_ptr beforeMailbox, shared_ptr mbox) +void mailboxList::insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox) { m_list.insertAddressBefore(beforeMailbox, mbox); } -void mailboxList::insertMailboxBefore(const size_t pos, shared_ptr mbox) +void mailboxList::insertMailboxBefore(const size_t pos, const shared_ptr & mbox) { m_list.insertAddressBefore(pos, mbox); } -void mailboxList::insertMailboxAfter(shared_ptr afterMailbox, shared_ptr mbox) +void mailboxList::insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox) { m_list.insertAddressAfter(afterMailbox, mbox); } -void mailboxList::insertMailboxAfter(const size_t pos, shared_ptr mbox) +void mailboxList::insertMailboxAfter(const size_t pos, const shared_ptr & mbox) { m_list.insertAddressAfter(pos, mbox); } -void mailboxList::removeMailbox(shared_ptr mbox) +void mailboxList::removeMailbox(const shared_ptr & mbox) { m_list.removeAddress(mbox); } diff --git a/src/vmime/mailboxList.hpp b/src/vmime/mailboxList.hpp index 125c238e..aca39136 100644 --- a/src/vmime/mailboxList.hpp +++ b/src/vmime/mailboxList.hpp @@ -57,7 +57,7 @@ public: * * @param mbox mailbox to append */ - void appendMailbox(shared_ptr mbox); + void appendMailbox(const shared_ptr & mbox); /** Insert a new mailbox before the specified mailbox. * @@ -65,7 +65,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxBefore(shared_ptr beforeMailbox, shared_ptr mbox); + void insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox); /** Insert a new mailbox before the specified position. * @@ -74,7 +74,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxBefore(const size_t pos, shared_ptr mbox); + void insertMailboxBefore(const size_t pos, const shared_ptr & mbox); /** Insert a new mailbox after the specified mailbox. * @@ -82,7 +82,7 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxAfter(shared_ptr afterMailbox, shared_ptr mbox); + void insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox); /** Insert a new mailbox after the specified position. * @@ -90,14 +90,14 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxAfter(const size_t pos, shared_ptr mbox); + void insertMailboxAfter(const size_t pos, const shared_ptr & mbox); /** Remove the specified mailbox from the list. * * @param mbox mailbox to remove * @throw std::out_of_range if the mailbox is not in the list */ - void removeMailbox(shared_ptr mbox); + void removeMailbox(const shared_ptr & mbox); /** Remove the mailbox at the specified position. * diff --git a/src/vmime/mdn/MDNHelper.cpp b/src/vmime/mdn/MDNHelper.cpp index 1205aef2..d416532e 100644 --- a/src/vmime/mdn/MDNHelper.cpp +++ b/src/vmime/mdn/MDNHelper.cpp @@ -38,7 +38,7 @@ namespace vmime { namespace mdn { -void MDNHelper::attachMDNRequest(shared_ptr msg, const mailboxList& mailboxes) +void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailboxList& mailboxes) { shared_ptr
hdr = msg->getHeader(); @@ -46,7 +46,7 @@ void MDNHelper::attachMDNRequest(shared_ptr msg, const mailboxList& ma } -void MDNHelper::attachMDNRequest(shared_ptr msg, const mailbox& mbox) +void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailbox& mbox) { mailboxList mboxList; mboxList.appendMailbox(vmime::clone(mbox)); @@ -55,7 +55,7 @@ void MDNHelper::attachMDNRequest(shared_ptr msg, const mailbox& mbox) } -const std::vector MDNHelper::getPossibleMDNs(const shared_ptr msg) +const std::vector MDNHelper::getPossibleMDNs(const shared_ptr & msg) { std::vector result; @@ -74,7 +74,7 @@ const std::vector MDNHelper::getPossibleMDNs(const shared_ptr } -bool MDNHelper::isMDN(const shared_ptr msg) +bool MDNHelper::isMDN(const shared_ptr & msg) { const shared_ptr hdr = msg->getHeader(); @@ -103,7 +103,7 @@ bool MDNHelper::isMDN(const shared_ptr msg) } -receivedMDNInfos MDNHelper::getReceivedMDN(const shared_ptr msg) +receivedMDNInfos MDNHelper::getReceivedMDN(const shared_ptr & msg) { if (!isMDN(msg)) throw exceptions::invalid_argument(); @@ -112,7 +112,7 @@ receivedMDNInfos MDNHelper::getReceivedMDN(const shared_ptr msg) } -bool MDNHelper::needConfirmation(const shared_ptr msg) +bool MDNHelper::needConfirmation(const shared_ptr & msg) { shared_ptr hdr = msg->getHeader(); diff --git a/src/vmime/mdn/MDNHelper.hpp b/src/vmime/mdn/MDNHelper.hpp index 2584978f..d7ba2487 100644 --- a/src/vmime/mdn/MDNHelper.hpp +++ b/src/vmime/mdn/MDNHelper.hpp @@ -48,14 +48,14 @@ public: * @param msg message in which to add a MDN request * @param mailboxes list of mailboxes to which the MDN will be sent */ - static void attachMDNRequest(shared_ptr msg, const mailboxList& mailboxes); + static void attachMDNRequest(const shared_ptr & msg, const mailboxList& mailboxes); /** Attach a MDN request to the specified message. * * @param msg message in which to add a MDN request * @param mbox mailbox to which the MDN will be sent */ - static void attachMDNRequest(shared_ptr msg, const mailbox& mbox); + static void attachMDNRequest(const shared_ptr & msg, const mailbox& mbox); /** Return a list of possible MDNs that can be generated * for the specified message. @@ -63,14 +63,14 @@ public: * @param msg message for which to send a MDN * @return list of possible MDNs */ - static const std::vector getPossibleMDNs(const shared_ptr msg); + static const std::vector getPossibleMDNs(const shared_ptr & msg); /** Test whether the specified message is a MDN. * * @param msg message * @return true if the message is a MDN, false otherwise */ - static bool isMDN(const shared_ptr msg); + static bool isMDN(const shared_ptr & msg); /** If the specified message is a MDN, return information * about it. @@ -79,7 +79,7 @@ public: * @throw exceptions::invalid_argument if the message is not a MDN * @return information about the MDN */ - static receivedMDNInfos getReceivedMDN(const shared_ptr msg); + static receivedMDNInfos getReceivedMDN(const shared_ptr & msg); /** Check whether we need user confirmation for sending a MDN even * if he/she explicitely allowed automatic send of MDNs. This can @@ -88,7 +88,7 @@ public: * @param msg message for which to send a MDN * @return true if user confirmation should be asked, false otherwise */ - static bool needConfirmation(const shared_ptr msg); + static bool needConfirmation(const shared_ptr & msg); /** Build a new MDN for the message. The resulting MDN can then be * sent over SMTP transport service. diff --git a/src/vmime/mdn/receivedMDNInfos.cpp b/src/vmime/mdn/receivedMDNInfos.cpp index 53b2281e..6036fcec 100644 --- a/src/vmime/mdn/receivedMDNInfos.cpp +++ b/src/vmime/mdn/receivedMDNInfos.cpp @@ -30,7 +30,7 @@ namespace vmime { namespace mdn { -receivedMDNInfos::receivedMDNInfos(const shared_ptr msg) +receivedMDNInfos::receivedMDNInfos(const shared_ptr & msg) : m_msg(msg) { extract(); diff --git a/src/vmime/mdn/receivedMDNInfos.hpp b/src/vmime/mdn/receivedMDNInfos.hpp index c6953a24..f849a58e 100644 --- a/src/vmime/mdn/receivedMDNInfos.hpp +++ b/src/vmime/mdn/receivedMDNInfos.hpp @@ -44,7 +44,7 @@ class VMIME_EXPORT receivedMDNInfos : public MDNInfos { public: - receivedMDNInfos(const shared_ptr msg); + receivedMDNInfos(const shared_ptr & msg); receivedMDNInfos(const receivedMDNInfos& other); receivedMDNInfos& operator=(const receivedMDNInfos& other); diff --git a/src/vmime/mdn/sendableMDNInfos.cpp b/src/vmime/mdn/sendableMDNInfos.cpp index c145c3b6..85232c1f 100644 --- a/src/vmime/mdn/sendableMDNInfos.cpp +++ b/src/vmime/mdn/sendableMDNInfos.cpp @@ -28,7 +28,7 @@ namespace vmime { namespace mdn { -sendableMDNInfos::sendableMDNInfos(const shared_ptr msg, const mailbox& mbox) +sendableMDNInfos::sendableMDNInfos(const shared_ptr & msg, const mailbox& mbox) : m_msg(msg), m_mailbox(mbox) { } diff --git a/src/vmime/mdn/sendableMDNInfos.hpp b/src/vmime/mdn/sendableMDNInfos.hpp index e4f6d20d..2c40c3a8 100644 --- a/src/vmime/mdn/sendableMDNInfos.hpp +++ b/src/vmime/mdn/sendableMDNInfos.hpp @@ -42,7 +42,7 @@ class VMIME_EXPORT sendableMDNInfos : public MDNInfos { public: - sendableMDNInfos(const shared_ptr msg, const mailbox& mbox); + sendableMDNInfos(const shared_ptr & msg, const mailbox& mbox); sendableMDNInfos(const sendableMDNInfos& other); sendableMDNInfos& operator=(const sendableMDNInfos& other); diff --git a/src/vmime/messageBuilder.cpp b/src/vmime/messageBuilder.cpp index 64880483..445758c9 100644 --- a/src/vmime/messageBuilder.cpp +++ b/src/vmime/messageBuilder.cpp @@ -167,13 +167,13 @@ shared_ptr messageBuilder::construct() const } -void messageBuilder::attach(shared_ptr attach) +void messageBuilder::attach(const shared_ptr & attach) { appendAttachment(attach); } -void messageBuilder::appendAttachment(shared_ptr attach) +void messageBuilder::appendAttachment(const shared_ptr & attach) { m_attach.push_back(attach); } diff --git a/src/vmime/messageBuilder.hpp b/src/vmime/messageBuilder.hpp index af86e826..4b5e15ce 100644 --- a/src/vmime/messageBuilder.hpp +++ b/src/vmime/messageBuilder.hpp @@ -136,13 +136,13 @@ public: * * @param attach new attachment */ - void attach(shared_ptr attach); + void attach(const shared_ptr & attach); /** Attach a new object to the message. * * @param attach new attachment */ - void appendAttachment(shared_ptr attach); + void appendAttachment(const shared_ptr & attach); /** Remove the attachment at the specified position. * diff --git a/src/vmime/messageIdSequence.cpp b/src/vmime/messageIdSequence.cpp index 23b12773..4365fa3c 100644 --- a/src/vmime/messageIdSequence.cpp +++ b/src/vmime/messageIdSequence.cpp @@ -135,13 +135,13 @@ void messageIdSequence::generateImpl } -void messageIdSequence::appendMessageId(shared_ptr mid) +void messageIdSequence::appendMessageId(const shared_ptr & mid) { m_list.push_back(mid); } -void messageIdSequence::insertMessageIdBefore(shared_ptr beforeMid, shared_ptr mid) +void messageIdSequence::insertMessageIdBefore(const shared_ptr & beforeMid, const shared_ptr & mid) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), beforeMid); @@ -153,13 +153,13 @@ void messageIdSequence::insertMessageIdBefore(shared_ptr beforeMid, } -void messageIdSequence::insertMessageIdBefore(const size_t pos, shared_ptr mid) +void messageIdSequence::insertMessageIdBefore(const size_t pos, const shared_ptr & mid) { m_list.insert(m_list.begin() + pos, mid); } -void messageIdSequence::insertMessageIdAfter(shared_ptr afterMid, shared_ptr mid) +void messageIdSequence::insertMessageIdAfter(const shared_ptr & afterMid, const shared_ptr & mid) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), afterMid); @@ -171,13 +171,13 @@ void messageIdSequence::insertMessageIdAfter(shared_ptr afterMid, sh } -void messageIdSequence::insertMessageIdAfter(const size_t pos, shared_ptr mid) +void messageIdSequence::insertMessageIdAfter(const size_t pos, const shared_ptr & mid) { m_list.insert(m_list.begin() + pos + 1, mid); } -void messageIdSequence::removeMessageId(shared_ptr mid) +void messageIdSequence::removeMessageId(const shared_ptr & mid) { const std::vector >::iterator it = std::find (m_list.begin(), m_list.end(), mid); diff --git a/src/vmime/messageIdSequence.hpp b/src/vmime/messageIdSequence.hpp index 07f0c422..b0eea464 100644 --- a/src/vmime/messageIdSequence.hpp +++ b/src/vmime/messageIdSequence.hpp @@ -56,7 +56,7 @@ public: * * @param mid message-id to append */ - void appendMessageId(shared_ptr mid); + void appendMessageId(const shared_ptr & mid); /** Insert a new message-id before the specified message-id. * @@ -64,7 +64,7 @@ public: * @param mid message-id to insert * @throw exceptions::no_such_messageid if the message-id is not in the list */ - void insertMessageIdBefore(shared_ptr beforeMid, shared_ptr mid); + void insertMessageIdBefore(const shared_ptr & beforeMid, const shared_ptr & mid); /** Insert a new message-id before the specified position. * @@ -72,7 +72,7 @@ public: * the beginning of the list) * @param mid message-id to insert */ - void insertMessageIdBefore(const size_t pos, shared_ptr mid); + void insertMessageIdBefore(const size_t pos, const shared_ptr & mid); /** Insert a new message-id after the specified message-id. * @@ -80,21 +80,21 @@ public: * @param mid message-id to insert * @throw exceptions::no_such_message_id if the message-id is not in the list */ - void insertMessageIdAfter(shared_ptr afterMid, shared_ptr mid); + void insertMessageIdAfter(const shared_ptr & afterMid, const shared_ptr & mid); /** Insert a new message-id after the specified position. * * @param pos position of the message-id before the new message-id * @param mid message-id to insert */ - void insertMessageIdAfter(const size_t pos, shared_ptr mid); + void insertMessageIdAfter(const size_t pos, const shared_ptr & mid); /** Remove the specified message-id from the list. * * @param mid message-id to remove * @throw exceptions::no_such_message_id if the message-id is not in the list */ - void removeMessageId(shared_ptr mid); + void removeMessageId(const shared_ptr & mid); /** Remove the message-id at the specified position. * diff --git a/src/vmime/messageParser.cpp b/src/vmime/messageParser.cpp index 5fe219f3..c5295504 100644 --- a/src/vmime/messageParser.cpp +++ b/src/vmime/messageParser.cpp @@ -46,7 +46,7 @@ messageParser::messageParser(const string& buffer) } -messageParser::messageParser(shared_ptr msg) +messageParser::messageParser(const shared_ptr & msg) { parse(msg); } @@ -57,7 +57,7 @@ messageParser::~messageParser() } -void messageParser::parse(shared_ptr msg) +void messageParser::parse(const shared_ptr & msg) { // Header fields (if field is present, copy its value, else do nothing) #ifndef VMIME_BUILDING_DOC @@ -106,13 +106,13 @@ void messageParser::parse(shared_ptr msg) } -void messageParser::findAttachments(shared_ptr msg) +void messageParser::findAttachments(const shared_ptr & msg) { m_attach = attachmentHelper::findAttachmentsInMessage(msg); } -void messageParser::findTextParts(shared_ptr msg, shared_ptr part) +void messageParser::findTextParts(const shared_ptr & msg, const shared_ptr & part) { // Handle the case in which the message is not multipart: if the body part is // "text/*", take this part. @@ -156,7 +156,7 @@ void messageParser::findTextParts(shared_ptr msg, shared_ptr msg, shared_ptr part) +bool messageParser::findSubTextParts(const shared_ptr & msg, const shared_ptr & part) { // In general, all the text parts are contained in parallel in the same // parent part (or message). diff --git a/src/vmime/messageParser.hpp b/src/vmime/messageParser.hpp index c3a48f11..5413862d 100644 --- a/src/vmime/messageParser.hpp +++ b/src/vmime/messageParser.hpp @@ -49,7 +49,7 @@ class VMIME_EXPORT messageParser public: messageParser(const string& buffer); - messageParser(shared_ptr msg); + messageParser(const shared_ptr & msg); ~messageParser(); public: @@ -144,12 +144,12 @@ private: std::vector > m_textParts; - void parse(shared_ptr msg); + void parse(const shared_ptr & msg); - void findAttachments(shared_ptr msg); + void findAttachments(const shared_ptr & msg); - void findTextParts(shared_ptr msg, shared_ptr part); - bool findSubTextParts(shared_ptr msg, shared_ptr part); + void findTextParts(const shared_ptr & msg, const shared_ptr & part); + bool findSubTextParts(const shared_ptr & msg, const shared_ptr & part); }; diff --git a/src/vmime/misc/importanceHelper.cpp b/src/vmime/misc/importanceHelper.cpp index e1228ee1..ac298619 100644 --- a/src/vmime/misc/importanceHelper.cpp +++ b/src/vmime/misc/importanceHelper.cpp @@ -31,13 +31,13 @@ namespace vmime { namespace misc { -void importanceHelper::resetImportance(shared_ptr msg) +void importanceHelper::resetImportance(const shared_ptr & msg) { resetImportanceHeader(msg->getHeader()); } -void importanceHelper::resetImportanceHeader(shared_ptr
hdr) +void importanceHelper::resetImportanceHeader(const shared_ptr
& hdr) { shared_ptr fld; @@ -49,13 +49,13 @@ void importanceHelper::resetImportanceHeader(shared_ptr
hdr) } -importanceHelper::Importance importanceHelper::getImportance(shared_ptr msg) +importanceHelper::Importance importanceHelper::getImportance(const shared_ptr & msg) { return getImportanceHeader(msg->getHeader()); } -importanceHelper::Importance importanceHelper::getImportanceHeader(shared_ptr hdr) +importanceHelper::Importance importanceHelper::getImportanceHeader(const shared_ptr & hdr) { // Try "X-Priority" field shared_ptr fld = hdr->findField("X-Priority"); @@ -113,13 +113,13 @@ importanceHelper::Importance importanceHelper::getImportanceHeader(shared_ptr msg, const Importance i) +void importanceHelper::setImportance(const shared_ptr & msg, const Importance i) { setImportanceHeader(msg->getHeader(), i); } -void importanceHelper::setImportanceHeader(shared_ptr
hdr, const Importance i) +void importanceHelper::setImportanceHeader(const shared_ptr
& hdr, const Importance i) { // "X-Priority:" Field shared_ptr fld = hdr->getField("X-Priority"); diff --git a/src/vmime/misc/importanceHelper.hpp b/src/vmime/misc/importanceHelper.hpp index ae8297fc..18dc2364 100644 --- a/src/vmime/misc/importanceHelper.hpp +++ b/src/vmime/misc/importanceHelper.hpp @@ -58,13 +58,13 @@ public: * * @param msg message on which to reset importance */ - static void resetImportance(shared_ptr msg); + static void resetImportance(const shared_ptr & msg); /** Reset the importance of a message to the default importance. * * @param hdr message header on which to reset importance */ - static void resetImportanceHeader(shared_ptr
hdr); + static void resetImportanceHeader(const shared_ptr
& hdr); /** Return the importance of the specified message. * @@ -72,7 +72,7 @@ public: * @return importance of the message, or default importance is no * information about importance is given in the message */ - static Importance getImportance(shared_ptr msg); + static Importance getImportance(const shared_ptr & msg); /** Return the importance of a message, given its header. * @@ -80,21 +80,21 @@ public: * @return importance of the message, or default importance is no * information about importance is given in the message */ - static Importance getImportanceHeader(shared_ptr hdr); + static Importance getImportanceHeader(const shared_ptr & hdr); /** Set the importance of the specified message. * * @param msg message on which to set importance * @param i new message importance */ - static void setImportance(shared_ptr msg, const Importance i); + static void setImportance(const shared_ptr & msg, const Importance i); /** Set the importance of a message, given its header. * * @param hdr message header on which to set importance * @param i new message importance */ - static void setImportanceHeader(shared_ptr
hdr, const Importance i); + static void setImportanceHeader(const shared_ptr
& hdr, const Importance i); }; diff --git a/src/vmime/net/events.cpp b/src/vmime/net/events.cpp index 45f7f98e..6d056ae6 100644 --- a/src/vmime/net/events.cpp +++ b/src/vmime/net/events.cpp @@ -60,7 +60,7 @@ const char* messageCountEvent::EVENT_CLASS = "messageCountEvent"; messageCountEvent::messageCountEvent - (shared_ptr folder, const Types type, const std::vector & nums) + (const shared_ptr & folder, const Types type, const std::vector & nums) : m_folder(folder), m_type(type) { m_nums.resize(nums.size()); @@ -96,7 +96,7 @@ const char* messageChangedEvent::EVENT_CLASS = "messageChangedEvent"; messageChangedEvent::messageChangedEvent - (shared_ptr folder, const Types type, const std::vector & nums) + (const shared_ptr & folder, const Types type, const std::vector & nums) : m_folder(folder), m_type(type) { m_nums.resize(nums.size()); @@ -129,7 +129,7 @@ const char* folderEvent::EVENT_CLASS = "folderEvent"; folderEvent::folderEvent - (shared_ptr folder, const Types type, + (const shared_ptr & folder, const Types type, const utility::path& oldPath, const utility::path& newPath) : m_folder(folder), m_type(type), m_oldPath(oldPath), m_newPath(newPath) { diff --git a/src/vmime/net/events.hpp b/src/vmime/net/events.hpp index 60d15bd9..772c4d9d 100644 --- a/src/vmime/net/events.hpp +++ b/src/vmime/net/events.hpp @@ -75,7 +75,7 @@ public: }; - messageCountEvent(shared_ptr folder, const Types type, const std::vector & nums); + messageCountEvent(const shared_ptr & folder, const Types type, const std::vector & nums); /** Return the folder in which messages have been added/removed. * @@ -123,8 +123,8 @@ protected: public: - virtual void messagesAdded(shared_ptr event) = 0; - virtual void messagesRemoved(shared_ptr event) = 0; + virtual void messagesAdded(const shared_ptr & event) = 0; + virtual void messagesRemoved(const shared_ptr & event) = 0; }; @@ -144,7 +144,7 @@ public: }; - messageChangedEvent(shared_ptr folder, const Types type, const std::vector & nums); + messageChangedEvent(const shared_ptr & folder, const Types type, const std::vector & nums); /** Return the folder in which messages have changed. * @@ -192,7 +192,7 @@ protected: public: - virtual void messageChanged(shared_ptr event) = 0; + virtual void messageChanged(const shared_ptr & event) = 0; }; @@ -214,7 +214,7 @@ public: }; - folderEvent(shared_ptr folder, const Types type, const utility::path& oldPath, const utility::path& newPath); + folderEvent(const shared_ptr & folder, const Types type, const utility::path& oldPath, const utility::path& newPath); /** Return the folder on which the event occurred. * @@ -257,9 +257,9 @@ protected: public: - virtual void folderCreated(shared_ptr event) = 0; - virtual void folderRenamed(shared_ptr event) = 0; - virtual void folderDeleted(shared_ptr event) = 0; + virtual void folderCreated(const shared_ptr & event) = 0; + virtual void folderRenamed(const shared_ptr & event) = 0; + virtual void folderDeleted(const shared_ptr & event) = 0; }; diff --git a/src/vmime/net/folder.cpp b/src/vmime/net/folder.cpp index 78ed5131..38f60523 100644 --- a/src/vmime/net/folder.cpp +++ b/src/vmime/net/folder.cpp @@ -60,7 +60,7 @@ void folder::removeMessageChangedListener(events::messageChangedListener* l) } -void folder::notifyMessageChanged(shared_ptr event) +void folder::notifyMessageChanged(const shared_ptr & event) { for (std::list ::iterator it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it) @@ -82,7 +82,7 @@ void folder::removeMessageCountListener(events::messageCountListener* l) } -void folder::notifyMessageCount(shared_ptr event) +void folder::notifyMessageCount(const shared_ptr & event) { for (std::list ::iterator it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it) @@ -104,7 +104,7 @@ void folder::removeFolderListener(events::folderListener* l) } -void folder::notifyFolder(shared_ptr event) +void folder::notifyFolder(const shared_ptr & event) { for (std::list ::iterator it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it) @@ -114,7 +114,7 @@ void folder::notifyFolder(shared_ptr event) } -void folder::notifyEvent(shared_ptr event) +void folder::notifyEvent(const shared_ptr & event) { if (event->getClass() == events::messageCountEvent::EVENT_CLASS) { diff --git a/src/vmime/net/folder.hpp b/src/vmime/net/folder.hpp index 5186bae0..8117d7d1 100644 --- a/src/vmime/net/folder.hpp +++ b/src/vmime/net/folder.hpp @@ -274,7 +274,7 @@ public: * @throw exceptions::net_exception if an error occurs */ virtual messageSet addMessage - (shared_ptr msg, + (const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0; @@ -366,7 +366,7 @@ public: * @param attribs set of attributes to fetch * @throw exceptions::net_exception if an error occurs */ - virtual void fetchMessage(shared_ptr msg, const fetchAttributes& attribs) = 0; + virtual void fetchMessage(const shared_ptr & msg, const fetchAttributes& attribs) = 0; /** Get new references to messages in this folder, given either their * sequence numbers or UIDs, and fetch objects for them at the same time. @@ -408,10 +408,10 @@ public: protected: - void notifyMessageChanged(shared_ptr event); - void notifyMessageCount(shared_ptr event); - void notifyFolder(shared_ptr event); - void notifyEvent(shared_ptr event); + void notifyMessageChanged(const shared_ptr & event); + void notifyMessageCount(const shared_ptr & event); + void notifyFolder(const shared_ptr & event); + void notifyEvent(const shared_ptr & event); private: diff --git a/src/vmime/net/imap/IMAPCommand.cpp b/src/vmime/net/imap/IMAPCommand.cpp index b1840d8d..908b9152 100644 --- a/src/vmime/net/imap/IMAPCommand.cpp +++ b/src/vmime/net/imap/IMAPCommand.cpp @@ -396,7 +396,7 @@ const string IMAPCommand::getTraceText() const } -void IMAPCommand::send(shared_ptr conn) +void IMAPCommand::send(const shared_ptr & conn) { conn->sendCommand(dynamicCast (shared_from_this())); } diff --git a/src/vmime/net/imap/IMAPCommand.hpp b/src/vmime/net/imap/IMAPCommand.hpp index dd499859..09f34c66 100644 --- a/src/vmime/net/imap/IMAPCommand.hpp +++ b/src/vmime/net/imap/IMAPCommand.hpp @@ -85,7 +85,7 @@ public: * * @param conn connection onto which the command will be sent */ - virtual void send(shared_ptr conn); + virtual void send(const shared_ptr & conn); /** Returns the full text of the command, including command name * and parameters (if any). This is the text that will be sent diff --git a/src/vmime/net/imap/IMAPConnection.cpp b/src/vmime/net/imap/IMAPConnection.cpp index 0cc08178..7fc86188 100644 --- a/src/vmime/net/imap/IMAPConnection.cpp +++ b/src/vmime/net/imap/IMAPConnection.cpp @@ -66,7 +66,7 @@ namespace net { namespace imap { -IMAPConnection::IMAPConnection(shared_ptr store, shared_ptr auth) +IMAPConnection::IMAPConnection(const shared_ptr & store, const shared_ptr & auth) : m_store(store), m_auth(auth), m_socket(null), m_parser(null), m_tag(null), m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(null), m_secured(false), m_firstTag(true), m_capabilitiesFetched(false), m_noModSeq(false) @@ -754,7 +754,7 @@ void IMAPConnection::initHierarchySeparator() } -void IMAPConnection::sendCommand(shared_ptr cmd) +void IMAPConnection::sendCommand(const shared_ptr & cmd) { if (!m_firstTag) ++(*m_tag); @@ -830,7 +830,7 @@ shared_ptr IMAPConnection::getSocket() const } -void IMAPConnection::setSocket(shared_ptr sok) +void IMAPConnection::setSocket(const shared_ptr & sok) { m_socket = sok; m_parser->setSocket(sok); diff --git a/src/vmime/net/imap/IMAPConnection.hpp b/src/vmime/net/imap/IMAPConnection.hpp index 0ce9092d..9a277f7c 100644 --- a/src/vmime/net/imap/IMAPConnection.hpp +++ b/src/vmime/net/imap/IMAPConnection.hpp @@ -56,7 +56,7 @@ class VMIME_EXPORT IMAPConnection : public object, public enable_shared_from_thi { public: - IMAPConnection(shared_ptr store, shared_ptr auth); + IMAPConnection(const shared_ptr & store, const shared_ptr & auth); ~IMAPConnection(); @@ -81,7 +81,7 @@ public: char hierarchySeparator() const; - void sendCommand(shared_ptr cmd); + void sendCommand(const shared_ptr & cmd); void sendRaw(const byte_t* buffer, const size_t count); IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL); @@ -104,7 +104,7 @@ public: shared_ptr getConnectionInfos() const; shared_ptr getSocket() const; - void setSocket(shared_ptr sok); + void setSocket(const shared_ptr & sok); shared_ptr getTracer(); diff --git a/src/vmime/net/imap/IMAPFolder.cpp b/src/vmime/net/imap/IMAPFolder.cpp index 1fbe1331..a142f7f5 100644 --- a/src/vmime/net/imap/IMAPFolder.cpp +++ b/src/vmime/net/imap/IMAPFolder.cpp @@ -52,7 +52,7 @@ namespace net { namespace imap { -IMAPFolder::IMAPFolder(const folder::path& path, shared_ptr store, shared_ptr attribs) +IMAPFolder::IMAPFolder(const folder::path& path, const shared_ptr & store, const shared_ptr & attribs) : m_store(store), m_connection(store->connection()), m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1), m_open(false), m_attribs(attribs) @@ -837,7 +837,7 @@ void IMAPFolder::fetchMessages(std::vector >& msg, const f } -void IMAPFolder::fetchMessage(shared_ptr msg, const fetchAttributes& options) +void IMAPFolder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) { std::vector > msgs; msgs.push_back(msg); @@ -1044,7 +1044,7 @@ void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const messageSet IMAPFolder::addMessage - (shared_ptr msg, const int flags, + (const shared_ptr & msg, const int flags, vmime::datetime* date, utility::progressListener* progress) { std::ostringstream oss; diff --git a/src/vmime/net/imap/IMAPFolder.hpp b/src/vmime/net/imap/IMAPFolder.hpp index d4e1c34a..15663232 100644 --- a/src/vmime/net/imap/IMAPFolder.hpp +++ b/src/vmime/net/imap/IMAPFolder.hpp @@ -63,7 +63,7 @@ private: friend class IMAPMessage; IMAPFolder(const IMAPFolder&); - IMAPFolder(const folder::path& path, shared_ptr store, shared_ptr attribs); + IMAPFolder(const folder::path& path, const shared_ptr & store, const shared_ptr & attribs); public: @@ -103,7 +103,7 @@ public: void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); messageSet addMessage - (shared_ptr msg, + (const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); @@ -131,7 +131,7 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); - void fetchMessage(shared_ptr msg, const fetchAttributes& options); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); std::vector > getAndFetchMessages (const messageSet& msgs, const fetchAttributes& attribs); diff --git a/src/vmime/net/imap/IMAPMessage.cpp b/src/vmime/net/imap/IMAPMessage.cpp index 123a94a9..f0d2ebd3 100644 --- a/src/vmime/net/imap/IMAPMessage.cpp +++ b/src/vmime/net/imap/IMAPMessage.cpp @@ -101,7 +101,7 @@ private: // -IMAPMessage::IMAPMessage(shared_ptr folder, const size_t num) +IMAPMessage::IMAPMessage(const shared_ptr & folder, const size_t num) : m_folder(folder), m_num(num), m_size(-1U), m_flags(FLAG_UNDEFINED), m_expunged(false), m_modseq(0), m_structure(null) { @@ -109,7 +109,7 @@ IMAPMessage::IMAPMessage(shared_ptr folder, const size_t num) } -IMAPMessage::IMAPMessage(shared_ptr folder, const size_t num, const uid& uid) +IMAPMessage::IMAPMessage(const shared_ptr & folder, const size_t num, const uid& uid) : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), m_expunged(false), m_uid(uid), m_modseq(0), m_structure(null) { @@ -225,7 +225,7 @@ void IMAPMessage::extract void IMAPMessage::extractPart - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, @@ -241,7 +241,7 @@ void IMAPMessage::extractPart } -void IMAPMessage::fetchPartHeader(shared_ptr p) +void IMAPMessage::fetchPartHeader(const shared_ptr & p) { shared_ptr folder = m_folder.lock(); @@ -257,7 +257,7 @@ void IMAPMessage::fetchPartHeader(shared_ptr p) } -void IMAPMessage::fetchPartHeaderForStructure(shared_ptr str) +void IMAPMessage::fetchPartHeaderForStructure(const shared_ptr & str) { for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i) { @@ -273,7 +273,7 @@ void IMAPMessage::fetchPartHeaderForStructure(shared_ptr str) size_t IMAPMessage::extractImpl - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, @@ -611,7 +611,7 @@ void IMAPMessage::setFlags(const int flags, const int mode) void IMAPMessage::constructParsedMessage - (shared_ptr parentPart, shared_ptr str, int level) + (const shared_ptr & parentPart, const shared_ptr & str, int level) { if (level == 0) { diff --git a/src/vmime/net/imap/IMAPMessage.hpp b/src/vmime/net/imap/IMAPMessage.hpp index 93545f22..48722127 100644 --- a/src/vmime/net/imap/IMAPMessage.hpp +++ b/src/vmime/net/imap/IMAPMessage.hpp @@ -59,8 +59,8 @@ private: public: - IMAPMessage(shared_ptr folder, const size_t num); - IMAPMessage(shared_ptr folder, const size_t num, const uid& uid); + IMAPMessage(const shared_ptr & folder, const size_t num); + IMAPMessage(const shared_ptr & folder, const size_t num, const uid& uid); ~IMAPMessage(); @@ -99,13 +99,13 @@ public: const bool peek = false) const; void extractPart - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; - void fetchPartHeader(shared_ptr p); + void fetchPartHeader(const shared_ptr & p); shared_ptr getParsedMessage(); @@ -135,7 +135,7 @@ private: * * @param str structure for which to fetch parts headers */ - void fetchPartHeaderForStructure(shared_ptr str); + void fetchPartHeaderForStructure(const shared_ptr & str); /** Recursively contruct parsed message from structure. * Called by getParsedMessage(). @@ -144,7 +144,7 @@ private: * @param str structure for which to construct part * @param level current nesting level (0 is root) */ - void constructParsedMessage(shared_ptr parentPart, shared_ptr str, int level = 0); + void constructParsedMessage(const shared_ptr & parentPart, const shared_ptr & str, int level = 0); enum ExtractFlags @@ -155,7 +155,7 @@ private: }; size_t extractImpl - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, diff --git a/src/vmime/net/imap/IMAPMessagePart.cpp b/src/vmime/net/imap/IMAPMessagePart.cpp index 1539f2ca..08e6f92b 100644 --- a/src/vmime/net/imap/IMAPMessagePart.cpp +++ b/src/vmime/net/imap/IMAPMessagePart.cpp @@ -36,7 +36,7 @@ namespace net { namespace imap { -IMAPMessagePart::IMAPMessagePart(shared_ptr parent, const size_t number, const IMAPParser::body_type_mpart* mpart) +IMAPMessagePart::IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_mpart* mpart) : m_parent(parent), m_header(null), m_number(number), m_size(0) { m_mediaType = vmime::mediaType @@ -44,7 +44,7 @@ IMAPMessagePart::IMAPMessagePart(shared_ptr parent, const size } -IMAPMessagePart::IMAPMessagePart(shared_ptr parent, const size_t number, const IMAPParser::body_type_1part* part) +IMAPMessagePart::IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_1part* part) : m_parent(parent), m_header(null), m_number(number), m_size(0) { if (part->body_type_text()) @@ -127,7 +127,7 @@ shared_ptr IMAPMessagePart::getHeader() const // static shared_ptr IMAPMessagePart::create - (shared_ptr parent, const size_t number, const IMAPParser::body* body) + (const shared_ptr & parent, const size_t number, const IMAPParser::body* body) { if (body->body_type_mpart()) { diff --git a/src/vmime/net/imap/IMAPMessagePart.hpp b/src/vmime/net/imap/IMAPMessagePart.hpp index 3b00887b..ab0d1a6f 100644 --- a/src/vmime/net/imap/IMAPMessagePart.hpp +++ b/src/vmime/net/imap/IMAPMessagePart.hpp @@ -48,8 +48,8 @@ class VMIME_EXPORT IMAPMessagePart : public messagePart { public: - IMAPMessagePart(shared_ptr parent, const size_t number, const IMAPParser::body_type_mpart* mpart); - IMAPMessagePart(shared_ptr parent, const size_t number, const IMAPParser::body_type_1part* part); + IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_mpart* mpart); + IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_1part* part); shared_ptr getStructure() const; shared_ptr getStructure(); @@ -64,7 +64,7 @@ public: static shared_ptr create - (shared_ptr parent, const size_t number, const IMAPParser::body* body); + (const shared_ptr & parent, const size_t number, const IMAPParser::body* body); header& getOrCreateHeader(); diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp index 1f53f082..32a2a75b 100644 --- a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp @@ -43,7 +43,7 @@ namespace imap { IMAPMessagePartContentHandler::IMAPMessagePartContentHandler - (shared_ptr msg, shared_ptr part, const vmime::encoding& encoding) + (const shared_ptr & msg, const shared_ptr & part, const vmime::encoding& encoding) : m_message(msg), m_part(part), m_encoding(encoding) { } diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp index cb52b2e3..8314fa95 100644 --- a/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp @@ -44,7 +44,7 @@ class VMIME_EXPORT IMAPMessagePartContentHandler : public contentHandler { public: - IMAPMessagePartContentHandler(shared_ptr msg, shared_ptr part, const vmime::encoding& encoding); + IMAPMessagePartContentHandler(const shared_ptr & msg, const shared_ptr & part, const vmime::encoding& encoding); shared_ptr clone() const; diff --git a/src/vmime/net/imap/IMAPMessageStructure.cpp b/src/vmime/net/imap/IMAPMessageStructure.cpp index 689c495d..1e6c1b32 100644 --- a/src/vmime/net/imap/IMAPMessageStructure.cpp +++ b/src/vmime/net/imap/IMAPMessageStructure.cpp @@ -47,7 +47,7 @@ IMAPMessageStructure::IMAPMessageStructure(const IMAPParser::body* body) } -IMAPMessageStructure::IMAPMessageStructure(shared_ptr parent, const std::vector & list) +IMAPMessageStructure::IMAPMessageStructure(const shared_ptr & parent, const std::vector & list) { size_t number = 0; diff --git a/src/vmime/net/imap/IMAPMessageStructure.hpp b/src/vmime/net/imap/IMAPMessageStructure.hpp index 44b6d6f0..f24e518c 100644 --- a/src/vmime/net/imap/IMAPMessageStructure.hpp +++ b/src/vmime/net/imap/IMAPMessageStructure.hpp @@ -50,7 +50,7 @@ public: IMAPMessageStructure(); IMAPMessageStructure(const IMAPParser::body* body); - IMAPMessageStructure(shared_ptr parent, const std::vector & list); + IMAPMessageStructure(const shared_ptr & parent, const std::vector & list); shared_ptr getPartAt(const size_t x) const; shared_ptr getPartAt(const size_t x); diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp index bad87769..33d091cc 100644 --- a/src/vmime/net/imap/IMAPParser.hpp +++ b/src/vmime/net/imap/IMAPParser.hpp @@ -273,7 +273,7 @@ public: * * @param tag IMAP command tag */ - void setTag(shared_ptr tag) + void setTag(const shared_ptr & tag) { m_tag = tag; } @@ -292,7 +292,7 @@ public: * * @param sok socket */ - void setSocket(shared_ptr sok) + void setSocket(const shared_ptr & sok) { m_socket = sok; } @@ -301,7 +301,7 @@ public: * * @param toh timeout handler */ - void setTimeoutHandler(shared_ptr toh) + void setTimeoutHandler(const shared_ptr & toh) { m_timeoutHandler = toh; } @@ -310,7 +310,7 @@ public: * * @param tr tracer */ - void setTracer(shared_ptr tr) + void setTracer(const shared_ptr & tr) { m_tracer = tr; } diff --git a/src/vmime/net/imap/IMAPSStore.cpp b/src/vmime/net/imap/IMAPSStore.cpp index c9e64f5b..f70c0915 100644 --- a/src/vmime/net/imap/IMAPSStore.cpp +++ b/src/vmime/net/imap/IMAPSStore.cpp @@ -35,7 +35,7 @@ namespace net { namespace imap { -IMAPSStore::IMAPSStore(shared_ptr sess, shared_ptr auth) +IMAPSStore::IMAPSStore(const shared_ptr & sess, const shared_ptr & auth) : IMAPStore(sess, auth, true) { } diff --git a/src/vmime/net/imap/IMAPSStore.hpp b/src/vmime/net/imap/IMAPSStore.hpp index 9d27bdd0..8d6896d7 100644 --- a/src/vmime/net/imap/IMAPSStore.hpp +++ b/src/vmime/net/imap/IMAPSStore.hpp @@ -46,7 +46,7 @@ class VMIME_EXPORT IMAPSStore : public IMAPStore { public: - IMAPSStore(shared_ptr sess, shared_ptr auth); + IMAPSStore(const shared_ptr & sess, const shared_ptr & auth); ~IMAPSStore(); const string getProtocolName() const; diff --git a/src/vmime/net/imap/IMAPStore.cpp b/src/vmime/net/imap/IMAPStore.cpp index bf93f284..7abfe8ae 100644 --- a/src/vmime/net/imap/IMAPStore.cpp +++ b/src/vmime/net/imap/IMAPStore.cpp @@ -44,7 +44,7 @@ namespace net { namespace imap { -IMAPStore::IMAPStore(shared_ptr sess, shared_ptr auth, const bool secured) +IMAPStore::IMAPStore(const shared_ptr & sess, const shared_ptr & auth, const bool secured) : store(sess, getInfosInstance(), auth), m_connection(null), m_isIMAPS(secured) { } diff --git a/src/vmime/net/imap/IMAPStore.hpp b/src/vmime/net/imap/IMAPStore.hpp index f854fadf..80932af4 100644 --- a/src/vmime/net/imap/IMAPStore.hpp +++ b/src/vmime/net/imap/IMAPStore.hpp @@ -60,7 +60,7 @@ class VMIME_EXPORT IMAPStore : public store public: - IMAPStore(shared_ptr sess, shared_ptr auth, const bool secured = false); + IMAPStore(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); ~IMAPStore(); const string getProtocolName() const; diff --git a/src/vmime/net/imap/IMAPUtils.cpp b/src/vmime/net/imap/IMAPUtils.cpp index 3e6b2677..bffc2c78 100644 --- a/src/vmime/net/imap/IMAPUtils.cpp +++ b/src/vmime/net/imap/IMAPUtils.cpp @@ -381,7 +381,7 @@ const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text) // static void IMAPUtils::mailboxFlagsToFolderAttributes - (shared_ptr cnt, const IMAPParser::mailbox_flag_list* list, + (const shared_ptr & cnt, const IMAPParser::mailbox_flag_list* list, folderAttributes& attribs) { int specialUse = folderAttributes::SPECIALUSE_NONE; @@ -594,7 +594,7 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) // static shared_ptr IMAPUtils::buildFetchCommand - (shared_ptr cnt, const messageSet& msgs, const fetchAttributes& options) + (const shared_ptr & cnt, const messageSet& msgs, const fetchAttributes& options) { // Example: // C: A654 FETCH 2:4 (FLAGS BODY[HEADER.FIELDS (DATE FROM)]) diff --git a/src/vmime/net/imap/IMAPUtils.hpp b/src/vmime/net/imap/IMAPUtils.hpp index 6140855d..a7daf736 100644 --- a/src/vmime/net/imap/IMAPUtils.hpp +++ b/src/vmime/net/imap/IMAPUtils.hpp @@ -74,7 +74,7 @@ public: * @param attribs reference to an object holding folder attributes */ static void mailboxFlagsToFolderAttributes - (shared_ptr cnt, + (const shared_ptr & cnt, const IMAPParser::mailbox_flag_list* list, folderAttributes& attribs); @@ -98,7 +98,7 @@ public: * @return fetch request */ static shared_ptr buildFetchCommand - (shared_ptr cnt, const messageSet& msgs, const fetchAttributes& options); + (const shared_ptr & cnt, const messageSet& msgs, const fetchAttributes& options); /** Convert a parser-style address list to a mailbox list. * @@ -124,7 +124,7 @@ public: private: static const string buildFetchRequestImpl - (shared_ptr cnt, const string& mode, const string& set, const int options); + (const shared_ptr & cnt, const string& mode, const string& set, const int options); }; diff --git a/src/vmime/net/maildir/format/courierMaildirFormat.cpp b/src/vmime/net/maildir/format/courierMaildirFormat.cpp index 6d460d5e..78753796 100644 --- a/src/vmime/net/maildir/format/courierMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/courierMaildirFormat.cpp @@ -41,7 +41,7 @@ namespace maildir { namespace format { -courierMaildirFormat::courierMaildirFormat(shared_ptr ctx) +courierMaildirFormat::courierMaildirFormat(const shared_ptr & ctx) : maildirFormat(ctx) { } diff --git a/src/vmime/net/maildir/format/courierMaildirFormat.hpp b/src/vmime/net/maildir/format/courierMaildirFormat.hpp index b8443426..6b6841e2 100644 --- a/src/vmime/net/maildir/format/courierMaildirFormat.hpp +++ b/src/vmime/net/maildir/format/courierMaildirFormat.hpp @@ -47,7 +47,7 @@ class VMIME_EXPORT courierMaildirFormat : public maildirFormat { public: - courierMaildirFormat(shared_ptr ctx); + courierMaildirFormat(const shared_ptr & ctx); /* Folder types: diff --git a/src/vmime/net/maildir/format/kmailMaildirFormat.cpp b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp index 975752a5..c52a2f45 100644 --- a/src/vmime/net/maildir/format/kmailMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp @@ -41,7 +41,7 @@ namespace maildir { namespace format { -kmailMaildirFormat::kmailMaildirFormat(shared_ptr ctx) +kmailMaildirFormat::kmailMaildirFormat(const shared_ptr & ctx) : maildirFormat(ctx) { } diff --git a/src/vmime/net/maildir/format/kmailMaildirFormat.hpp b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp index 98ca212e..854e60be 100644 --- a/src/vmime/net/maildir/format/kmailMaildirFormat.hpp +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp @@ -47,7 +47,7 @@ class VMIME_EXPORT kmailMaildirFormat : public maildirFormat { public: - kmailMaildirFormat(shared_ptr ctx); + kmailMaildirFormat(const shared_ptr & ctx); /* Folder types: diff --git a/src/vmime/net/maildir/maildirFolder.cpp b/src/vmime/net/maildir/maildirFolder.cpp index 8951cb1c..fec1294b 100644 --- a/src/vmime/net/maildir/maildirFolder.cpp +++ b/src/vmime/net/maildir/maildirFolder.cpp @@ -49,7 +49,7 @@ namespace net { namespace maildir { -maildirFolder::maildirFolder(const folder::path& path, shared_ptr store) +maildirFolder::maildirFolder(const folder::path& path, const shared_ptr & store) : m_store(store), m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1), m_open(false), m_unreadMessageCount(0), m_messageCount(0) @@ -708,7 +708,7 @@ void maildirFolder::setMessageFlags messageSet maildirFolder::addMessage - (shared_ptr msg, const int flags, + (const shared_ptr & msg, const int flags, vmime::datetime* date, utility::progressListener* progress) { std::ostringstream oss; @@ -1221,7 +1221,7 @@ void maildirFolder::fetchMessages(std::vector >& msg, } -void maildirFolder::fetchMessage(shared_ptr msg, const fetchAttributes& options) +void maildirFolder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) { shared_ptr store = m_store.lock(); diff --git a/src/vmime/net/maildir/maildirFolder.hpp b/src/vmime/net/maildir/maildirFolder.hpp index d6bdb7e8..ff0cff61 100644 --- a/src/vmime/net/maildir/maildirFolder.hpp +++ b/src/vmime/net/maildir/maildirFolder.hpp @@ -61,7 +61,7 @@ private: friend class maildirMessage; maildirFolder(const maildirFolder&) : folder() { } - maildirFolder(const folder::path& path, shared_ptr store); + maildirFolder(const folder::path& path, const shared_ptr & store); public: @@ -99,7 +99,7 @@ public: void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); - messageSet addMessage(shared_ptr msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + messageSet addMessage(const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); messageSet copyMessages(const folder::path& dest, const messageSet& msgs); @@ -116,7 +116,7 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); - void fetchMessage(shared_ptr msg, const fetchAttributes& options); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); std::vector > getAndFetchMessages (const messageSet& msgs, const fetchAttributes& attribs); diff --git a/src/vmime/net/maildir/maildirFormat.cpp b/src/vmime/net/maildir/maildirFormat.cpp index f7a3c8fe..5b0b3c2b 100644 --- a/src/vmime/net/maildir/maildirFormat.cpp +++ b/src/vmime/net/maildir/maildirFormat.cpp @@ -50,7 +50,7 @@ const utility::file::path::component maildirFormat::NEW_DIR("new", vmime::charse // maildirFormat::context // -maildirFormat::context::context(shared_ptr store) +maildirFormat::context::context(const shared_ptr & store) : m_store(store) { } @@ -66,7 +66,7 @@ shared_ptr maildirFormat::context::getStore() const // maildirFormat // -maildirFormat::maildirFormat(shared_ptr ctx) +maildirFormat::maildirFormat(const shared_ptr & ctx) : m_context(ctx) { } @@ -85,7 +85,7 @@ shared_ptr maildirFormat::getContext() const // static -shared_ptr maildirFormat::detect(shared_ptr store) +shared_ptr maildirFormat::detect(const shared_ptr & store) { shared_ptr ctx = make_shared (store); diff --git a/src/vmime/net/maildir/maildirFormat.hpp b/src/vmime/net/maildir/maildirFormat.hpp index c0daf288..7a95caf4 100644 --- a/src/vmime/net/maildir/maildirFormat.hpp +++ b/src/vmime/net/maildir/maildirFormat.hpp @@ -55,7 +55,7 @@ public: { public: - context(shared_ptr store); + context(const shared_ptr & store); shared_ptr getStore() const; @@ -146,7 +146,7 @@ public: * @param store of which to detect format * @return a Maildir format implementation for the specified store */ - static shared_ptr detect(shared_ptr store); + static shared_ptr detect(const shared_ptr & store); protected: @@ -155,7 +155,7 @@ protected: static const utility::file::path::component NEW_DIR; /**< Unread messages. */ - maildirFormat(shared_ptr ctx); + maildirFormat(const shared_ptr & ctx); /** Returns the current context. diff --git a/src/vmime/net/maildir/maildirMessage.cpp b/src/vmime/net/maildir/maildirMessage.cpp index faf00f6a..ea3d05a6 100644 --- a/src/vmime/net/maildir/maildirMessage.cpp +++ b/src/vmime/net/maildir/maildirMessage.cpp @@ -48,7 +48,7 @@ namespace net { namespace maildir { -maildirMessage::maildirMessage(shared_ptr folder, const size_t num) +maildirMessage::maildirMessage(const shared_ptr & folder, const size_t num) : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), m_expunged(false), m_structure(null) { @@ -160,7 +160,7 @@ void maildirMessage::extract(utility::outputStream& os, } -void maildirMessage::extractPart(shared_ptr p, utility::outputStream& os, +void maildirMessage::extractPart(const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, const bool peek) const { @@ -217,7 +217,7 @@ void maildirMessage::extractImpl(utility::outputStream& os, utility::progressLis } -void maildirMessage::fetchPartHeader(shared_ptr p) +void maildirMessage::fetchPartHeader(const shared_ptr & p) { shared_ptr folder = m_folder.lock(); @@ -252,7 +252,7 @@ void maildirMessage::fetchPartHeader(shared_ptr p) } -void maildirMessage::fetch(shared_ptr msgFolder, const fetchAttributes& options) +void maildirMessage::fetch(const shared_ptr & msgFolder, const fetchAttributes& options) { shared_ptr folder = m_folder.lock(); diff --git a/src/vmime/net/maildir/maildirMessage.hpp b/src/vmime/net/maildir/maildirMessage.hpp index 5cdabfc9..3e97a981 100644 --- a/src/vmime/net/maildir/maildirMessage.hpp +++ b/src/vmime/net/maildir/maildirMessage.hpp @@ -54,7 +54,7 @@ class VMIME_EXPORT maildirMessage : public message public: - maildirMessage(shared_ptr folder, const size_t num); + maildirMessage(const shared_ptr & folder, const size_t num); ~maildirMessage(); @@ -76,15 +76,15 @@ public: void setFlags(const int flags, const int mode = FLAG_MODE_SET); void extract(utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; - void extractPart(shared_ptr p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; + void extractPart(const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; - void fetchPartHeader(shared_ptr p); + void fetchPartHeader(const shared_ptr & p); shared_ptr getParsedMessage(); private: - void fetch(shared_ptr folder, const fetchAttributes& options); + void fetch(const shared_ptr & folder, const fetchAttributes& options); void onFolderClosed(); diff --git a/src/vmime/net/maildir/maildirMessagePart.cpp b/src/vmime/net/maildir/maildirMessagePart.cpp index 0b813749..787c0198 100644 --- a/src/vmime/net/maildir/maildirMessagePart.cpp +++ b/src/vmime/net/maildir/maildirMessagePart.cpp @@ -36,7 +36,7 @@ namespace net { namespace maildir { -maildirMessagePart::maildirMessagePart(shared_ptr parent, const size_t number, const bodyPart& part) +maildirMessagePart::maildirMessagePart(const shared_ptr & parent, const size_t number, const bodyPart& part) : m_parent(parent), m_header(null), m_number(number) { m_headerParsedOffset = part.getHeader()->getParsedOffset(); diff --git a/src/vmime/net/maildir/maildirMessagePart.hpp b/src/vmime/net/maildir/maildirMessagePart.hpp index db1aeb75..6aa80019 100644 --- a/src/vmime/net/maildir/maildirMessagePart.hpp +++ b/src/vmime/net/maildir/maildirMessagePart.hpp @@ -46,7 +46,7 @@ class maildirMessagePart : public messagePart { public: - maildirMessagePart(shared_ptr parent, const size_t number, const bodyPart& part); + maildirMessagePart(const shared_ptr & parent, const size_t number, const bodyPart& part); ~maildirMessagePart(); diff --git a/src/vmime/net/maildir/maildirMessageStructure.cpp b/src/vmime/net/maildir/maildirMessageStructure.cpp index 54eba981..e01c2a92 100644 --- a/src/vmime/net/maildir/maildirMessageStructure.cpp +++ b/src/vmime/net/maildir/maildirMessageStructure.cpp @@ -44,7 +44,7 @@ maildirMessageStructure::maildirMessageStructure() } -maildirMessageStructure::maildirMessageStructure(shared_ptr parent, const bodyPart& part) +maildirMessageStructure::maildirMessageStructure(const shared_ptr & parent, const bodyPart& part) { shared_ptr mpart = make_shared (parent, 0, part); mpart->initStructure(part); @@ -53,7 +53,7 @@ maildirMessageStructure::maildirMessageStructure(shared_ptr } -maildirMessageStructure::maildirMessageStructure(shared_ptr parent, const std::vector >& list) +maildirMessageStructure::maildirMessageStructure(const shared_ptr & parent, const std::vector >& list) { for (size_t i = 0 ; i < list.size() ; ++i) { diff --git a/src/vmime/net/maildir/maildirMessageStructure.hpp b/src/vmime/net/maildir/maildirMessageStructure.hpp index a43fc15c..fce5db6f 100644 --- a/src/vmime/net/maildir/maildirMessageStructure.hpp +++ b/src/vmime/net/maildir/maildirMessageStructure.hpp @@ -47,8 +47,8 @@ class maildirMessageStructure : public messageStructure public: maildirMessageStructure(); - maildirMessageStructure(shared_ptr parent, const bodyPart& part); - maildirMessageStructure(shared_ptr parent, const std::vector >& list); + maildirMessageStructure(const shared_ptr & parent, const bodyPart& part); + maildirMessageStructure(const shared_ptr & parent, const std::vector >& list); shared_ptr getPartAt(const size_t x) const; diff --git a/src/vmime/net/maildir/maildirStore.cpp b/src/vmime/net/maildir/maildirStore.cpp index 3c777551..4029eb7d 100644 --- a/src/vmime/net/maildir/maildirStore.cpp +++ b/src/vmime/net/maildir/maildirStore.cpp @@ -52,7 +52,7 @@ namespace net { namespace maildir { -maildirStore::maildirStore(shared_ptr sess, shared_ptr auth) +maildirStore::maildirStore(const shared_ptr & sess, const shared_ptr & auth) : store(sess, getInfosInstance(), auth), m_connected(false) { } diff --git a/src/vmime/net/maildir/maildirStore.hpp b/src/vmime/net/maildir/maildirStore.hpp index efadfdfe..ba7b8c13 100644 --- a/src/vmime/net/maildir/maildirStore.hpp +++ b/src/vmime/net/maildir/maildirStore.hpp @@ -60,7 +60,7 @@ class VMIME_EXPORT maildirStore : public store public: - maildirStore(shared_ptr sess, shared_ptr auth); + maildirStore(const shared_ptr & sess, const shared_ptr & auth); ~maildirStore(); const string getProtocolName() const; diff --git a/src/vmime/net/maildir/maildirUtils.cpp b/src/vmime/net/maildir/maildirUtils.cpp index b31eb931..1c75805a 100644 --- a/src/vmime/net/maildir/maildirUtils.cpp +++ b/src/vmime/net/maildir/maildirUtils.cpp @@ -175,7 +175,7 @@ const utility::file::path::component maildirUtils::generateId() } -void maildirUtils::recursiveFSDelete(shared_ptr dir) +void maildirUtils::recursiveFSDelete(const shared_ptr & dir) { shared_ptr files = dir->getFiles(); diff --git a/src/vmime/net/maildir/maildirUtils.hpp b/src/vmime/net/maildir/maildirUtils.hpp index 8899bdd7..6f120636 100644 --- a/src/vmime/net/maildir/maildirUtils.hpp +++ b/src/vmime/net/maildir/maildirUtils.hpp @@ -130,7 +130,7 @@ public: * * @param dir directory to delete */ - static void recursiveFSDelete(shared_ptr dir); + static void recursiveFSDelete(const shared_ptr & dir); /** Returns a list of message numbers given a message set. * diff --git a/src/vmime/net/message.hpp b/src/vmime/net/message.hpp index 4c64a1cf..80c9b974 100644 --- a/src/vmime/net/message.hpp +++ b/src/vmime/net/message.hpp @@ -321,7 +321,7 @@ public: * an exception if not supported. */ virtual void extractPart - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, @@ -332,7 +332,7 @@ public: * * @param p the part for which to fetch the header */ - virtual void fetchPartHeader(shared_ptr p) = 0; + virtual void fetchPartHeader(const shared_ptr & p) = 0; /** Get the RFC-822 message for this abstract message. * Warning: This may require getting some data (ie: structure and headers) from diff --git a/src/vmime/net/pop3/POP3Command.cpp b/src/vmime/net/pop3/POP3Command.cpp index 9dfaf17a..528746e0 100644 --- a/src/vmime/net/pop3/POP3Command.cpp +++ b/src/vmime/net/pop3/POP3Command.cpp @@ -245,7 +245,7 @@ const string POP3Command::getTraceText() const } -void POP3Command::send(shared_ptr conn) +void POP3Command::send(const shared_ptr & conn) { conn->getSocket()->send(m_text + "\r\n"); diff --git a/src/vmime/net/pop3/POP3Command.hpp b/src/vmime/net/pop3/POP3Command.hpp index 45aff661..7718ccb2 100644 --- a/src/vmime/net/pop3/POP3Command.hpp +++ b/src/vmime/net/pop3/POP3Command.hpp @@ -85,7 +85,7 @@ public: * * @param conn connection onto which the command will be sent */ - virtual void send(shared_ptr conn); + virtual void send(const shared_ptr & conn); /** Returns the full text of the command, including command name * and parameters (if any). diff --git a/src/vmime/net/pop3/POP3Connection.cpp b/src/vmime/net/pop3/POP3Connection.cpp index 27ab7aa2..ed098656 100644 --- a/src/vmime/net/pop3/POP3Connection.cpp +++ b/src/vmime/net/pop3/POP3Connection.cpp @@ -63,7 +63,7 @@ namespace pop3 { -POP3Connection::POP3Connection(shared_ptr store, shared_ptr auth) +POP3Connection::POP3Connection(const shared_ptr & store, const shared_ptr & auth) : m_store(store), m_auth(auth), m_socket(null), m_timeoutHandler(null), m_authenticated(false), m_secured(false), m_capabilitiesFetched(false) { diff --git a/src/vmime/net/pop3/POP3Connection.hpp b/src/vmime/net/pop3/POP3Connection.hpp index f40f1193..032be5cc 100644 --- a/src/vmime/net/pop3/POP3Connection.hpp +++ b/src/vmime/net/pop3/POP3Connection.hpp @@ -65,7 +65,7 @@ class VMIME_EXPORT POP3Connection : public object, public enable_shared_from_thi { public: - POP3Connection(shared_ptr store, shared_ptr auth); + POP3Connection(const shared_ptr & store, const shared_ptr & auth); virtual ~POP3Connection(); diff --git a/src/vmime/net/pop3/POP3Folder.cpp b/src/vmime/net/pop3/POP3Folder.cpp index 0e232c1a..8c34676e 100644 --- a/src/vmime/net/pop3/POP3Folder.cpp +++ b/src/vmime/net/pop3/POP3Folder.cpp @@ -45,7 +45,7 @@ namespace net { namespace pop3 { -POP3Folder::POP3Folder(const folder::path& path, shared_ptr store) +POP3Folder::POP3Folder(const folder::path& path, const shared_ptr & store) : m_store(store), m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1), m_open(false) @@ -420,7 +420,7 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f } -void POP3Folder::fetchMessage(shared_ptr msg, const fetchAttributes& options) +void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) { shared_ptr store = m_store.lock(); @@ -625,7 +625,7 @@ void POP3Folder::rename(const folder::path& /* newPath */) messageSet POP3Folder::addMessage - (shared_ptr /* msg */, const int /* flags */, + (const shared_ptr & /* msg */, const int /* flags */, vmime::datetime* /* date */, utility::progressListener* /* progress */) { throw exceptions::operation_not_supported(); diff --git a/src/vmime/net/pop3/POP3Folder.hpp b/src/vmime/net/pop3/POP3Folder.hpp index 339399d8..92be088b 100644 --- a/src/vmime/net/pop3/POP3Folder.hpp +++ b/src/vmime/net/pop3/POP3Folder.hpp @@ -59,7 +59,7 @@ private: friend class POP3Message; POP3Folder(const POP3Folder&); - POP3Folder(const folder::path& path, shared_ptr store); + POP3Folder(const folder::path& path, const shared_ptr & store); public: @@ -96,7 +96,7 @@ public: void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); - messageSet addMessage(shared_ptr msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + messageSet addMessage(const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); messageSet copyMessages(const folder::path& dest, const messageSet& msgs); @@ -113,7 +113,7 @@ public: void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); - void fetchMessage(shared_ptr msg, const fetchAttributes& options); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); std::vector > getAndFetchMessages (const messageSet& msgs, const fetchAttributes& attribs); diff --git a/src/vmime/net/pop3/POP3Message.cpp b/src/vmime/net/pop3/POP3Message.cpp index 67ad6d16..24d211a4 100644 --- a/src/vmime/net/pop3/POP3Message.cpp +++ b/src/vmime/net/pop3/POP3Message.cpp @@ -44,7 +44,7 @@ namespace net { namespace pop3 { -POP3Message::POP3Message(shared_ptr folder, const size_t num) +POP3Message::POP3Message(const shared_ptr & folder, const size_t num) : m_folder(folder), m_num(num), m_size(-1), m_deleted(false) { folder->registerMessage(this); @@ -166,7 +166,7 @@ void POP3Message::extract void POP3Message::extractPart - (shared_ptr /* p */, + (const shared_ptr & /* p */, utility::outputStream& /* os */, utility::progressListener* /* progress */, const size_t /* start */, const size_t /* length */, @@ -176,13 +176,13 @@ void POP3Message::extractPart } -void POP3Message::fetchPartHeader(shared_ptr /* p */) +void POP3Message::fetchPartHeader(const shared_ptr & /* p */) { throw exceptions::operation_not_supported(); } -void POP3Message::fetch(shared_ptr msgFolder, const fetchAttributes& options) +void POP3Message::fetch(const shared_ptr & msgFolder, const fetchAttributes& options) { shared_ptr folder = m_folder.lock(); diff --git a/src/vmime/net/pop3/POP3Message.hpp b/src/vmime/net/pop3/POP3Message.hpp index e4e3b079..7ac86a1b 100644 --- a/src/vmime/net/pop3/POP3Message.hpp +++ b/src/vmime/net/pop3/POP3Message.hpp @@ -56,7 +56,7 @@ private: public: - POP3Message(shared_ptr folder, const size_t num); + POP3Message(const shared_ptr & folder, const size_t num); ~POP3Message(); @@ -84,19 +84,19 @@ public: const bool peek = false) const; void extractPart - (shared_ptr p, + (const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; - void fetchPartHeader(shared_ptr p); + void fetchPartHeader(const shared_ptr & p); shared_ptr getParsedMessage(); private: - void fetch(shared_ptr folder, const fetchAttributes& options); + void fetch(const shared_ptr & folder, const fetchAttributes& options); void onFolderClosed(); diff --git a/src/vmime/net/pop3/POP3Response.cpp b/src/vmime/net/pop3/POP3Response.cpp index de3c2cf3..1d510fb3 100644 --- a/src/vmime/net/pop3/POP3Response.cpp +++ b/src/vmime/net/pop3/POP3Response.cpp @@ -46,14 +46,14 @@ namespace net { namespace pop3 { -POP3Response::POP3Response(shared_ptr sok, shared_ptr toh, shared_ptr tracer) +POP3Response::POP3Response(const shared_ptr & sok, const shared_ptr & toh, const shared_ptr & tracer) : m_socket(sok), m_timeoutHandler(toh), m_tracer(tracer) { } // static -shared_ptr POP3Response::readResponse(shared_ptr conn) +shared_ptr POP3Response::readResponse(const shared_ptr & conn) { shared_ptr resp = shared_ptr (new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())); @@ -73,7 +73,7 @@ shared_ptr POP3Response::readResponse(shared_ptr // static -shared_ptr POP3Response::readMultilineResponse(shared_ptr conn) +shared_ptr POP3Response::readMultilineResponse(const shared_ptr & conn) { shared_ptr resp = shared_ptr (new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())); @@ -112,7 +112,7 @@ shared_ptr POP3Response::readMultilineResponse(shared_ptr POP3Response::readLargeResponse - (shared_ptr conn, utility::outputStream& os, + (const shared_ptr & conn, utility::outputStream& os, utility::progressListener* progress, const size_t predictedSize) { shared_ptr resp = shared_ptr diff --git a/src/vmime/net/pop3/POP3Response.hpp b/src/vmime/net/pop3/POP3Response.hpp index d85b5405..4f0221e6 100644 --- a/src/vmime/net/pop3/POP3Response.hpp +++ b/src/vmime/net/pop3/POP3Response.hpp @@ -77,7 +77,7 @@ public: * @throws exceptions::operation_timed_out if no data * has been received within the granted time */ - static shared_ptr readResponse(shared_ptr conn); + static shared_ptr readResponse(const shared_ptr & conn); /** Receive and parse a multiline POP3 response from * the specified connection. @@ -87,7 +87,7 @@ public: * @throws exceptions::operation_timed_out if no data * has been received within the granted time */ - static shared_ptr readMultilineResponse(shared_ptr conn); + static shared_ptr readMultilineResponse(const shared_ptr & conn); /** Receive and parse a large POP3 response (eg. message data) * from the specified connection. @@ -101,7 +101,7 @@ public: * has been received within the granted time */ static shared_ptr readLargeResponse - (shared_ptr conn, utility::outputStream& os, + (const shared_ptr & conn, utility::outputStream& os, utility::progressListener* progress, const size_t predictedSize); @@ -144,7 +144,7 @@ public: private: - POP3Response(shared_ptr sok, shared_ptr toh, shared_ptr tracer); + POP3Response(const shared_ptr & sok, const shared_ptr & toh, const shared_ptr & tracer); void readResponseImpl(string& buffer, const bool multiLine); size_t readResponseImpl diff --git a/src/vmime/net/pop3/POP3SStore.cpp b/src/vmime/net/pop3/POP3SStore.cpp index f1c3da74..51e58f0e 100644 --- a/src/vmime/net/pop3/POP3SStore.cpp +++ b/src/vmime/net/pop3/POP3SStore.cpp @@ -35,7 +35,7 @@ namespace net { namespace pop3 { -POP3SStore::POP3SStore(shared_ptr sess, shared_ptr auth) +POP3SStore::POP3SStore(const shared_ptr & sess, const shared_ptr & auth) : POP3Store(sess, auth, true) { } diff --git a/src/vmime/net/pop3/POP3SStore.hpp b/src/vmime/net/pop3/POP3SStore.hpp index e60b4ef8..ad88fa10 100644 --- a/src/vmime/net/pop3/POP3SStore.hpp +++ b/src/vmime/net/pop3/POP3SStore.hpp @@ -46,7 +46,7 @@ class VMIME_EXPORT POP3SStore : public POP3Store { public: - POP3SStore(shared_ptr sess, shared_ptr auth); + POP3SStore(const shared_ptr & sess, const shared_ptr & auth); ~POP3SStore(); const string getProtocolName() const; diff --git a/src/vmime/net/pop3/POP3Store.cpp b/src/vmime/net/pop3/POP3Store.cpp index 4d1bb432..020cc55e 100644 --- a/src/vmime/net/pop3/POP3Store.cpp +++ b/src/vmime/net/pop3/POP3Store.cpp @@ -42,7 +42,7 @@ namespace net { namespace pop3 { -POP3Store::POP3Store(shared_ptr sess, shared_ptr auth, const bool secured) +POP3Store::POP3Store(const shared_ptr & sess, const shared_ptr & auth, const bool secured) : store(sess, getInfosInstance(), auth), m_isPOP3S(secured) { } diff --git a/src/vmime/net/pop3/POP3Store.hpp b/src/vmime/net/pop3/POP3Store.hpp index b35659a0..4737715a 100644 --- a/src/vmime/net/pop3/POP3Store.hpp +++ b/src/vmime/net/pop3/POP3Store.hpp @@ -59,7 +59,7 @@ class VMIME_EXPORT POP3Store : public store public: - POP3Store(shared_ptr sess, shared_ptr auth, const bool secured = false); + POP3Store(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); ~POP3Store(); const string getProtocolName() const; diff --git a/src/vmime/net/pop3/POP3Utils.cpp b/src/vmime/net/pop3/POP3Utils.cpp index 0649fb79..cb17ea9b 100644 --- a/src/vmime/net/pop3/POP3Utils.cpp +++ b/src/vmime/net/pop3/POP3Utils.cpp @@ -39,7 +39,7 @@ namespace pop3 { // static -void POP3Utils::parseMultiListOrUidlResponse(shared_ptr response, std::map & result) +void POP3Utils::parseMultiListOrUidlResponse(const shared_ptr & response, std::map & result) { std::map ids; diff --git a/src/vmime/net/pop3/POP3Utils.hpp b/src/vmime/net/pop3/POP3Utils.hpp index c7d15b07..b9b2d555 100644 --- a/src/vmime/net/pop3/POP3Utils.hpp +++ b/src/vmime/net/pop3/POP3Utils.hpp @@ -64,7 +64,7 @@ public: * number to its corresponding data (either UID or size) */ static void parseMultiListOrUidlResponse - (shared_ptr response, std::map & result); + (const shared_ptr & response, std::map & result); /** Returns a list of message numbers given a message set. * diff --git a/src/vmime/net/sendmail/sendmailTransport.cpp b/src/vmime/net/sendmail/sendmailTransport.cpp index 822e1114..b911b129 100644 --- a/src/vmime/net/sendmail/sendmailTransport.cpp +++ b/src/vmime/net/sendmail/sendmailTransport.cpp @@ -58,7 +58,7 @@ namespace net { namespace sendmail { -sendmailTransport::sendmailTransport(shared_ptr sess, shared_ptr auth) +sendmailTransport::sendmailTransport(const shared_ptr & sess, const shared_ptr & auth) : transport(sess, getInfosInstance(), auth), m_connected(false) { } @@ -175,7 +175,7 @@ void sendmailTransport::send void sendmailTransport::internalSend - (const std::vector args, utility::inputStream& is, + (const std::vector & args, utility::inputStream& is, const size_t size, utility::progressListener* progress) { const utility::file::path path = vmime::platform::getHandler()-> diff --git a/src/vmime/net/sendmail/sendmailTransport.hpp b/src/vmime/net/sendmail/sendmailTransport.hpp index d1c6aec0..da419f95 100644 --- a/src/vmime/net/sendmail/sendmailTransport.hpp +++ b/src/vmime/net/sendmail/sendmailTransport.hpp @@ -50,7 +50,7 @@ class VMIME_EXPORT sendmailTransport : public transport { public: - sendmailTransport(shared_ptr sess, shared_ptr auth); + sendmailTransport(const shared_ptr & sess, const shared_ptr & auth); ~sendmailTransport(); const string getProtocolName() const; @@ -79,7 +79,7 @@ private: void internalDisconnect(); - void internalSend(const std::vector args, utility::inputStream& is, + void internalSend(const std::vector & args, utility::inputStream& is, const size_t size, utility::progressListener* progress); diff --git a/src/vmime/net/service.cpp b/src/vmime/net/service.cpp index 3cf94d5e..055f34fa 100644 --- a/src/vmime/net/service.cpp +++ b/src/vmime/net/service.cpp @@ -48,8 +48,8 @@ namespace vmime { namespace net { -service::service(shared_ptr sess, const serviceInfos& /* infos */, - shared_ptr auth) +service::service(const shared_ptr & sess, const serviceInfos& /* infos */, + const shared_ptr & auth) : m_session(sess), m_auth(auth) { if (!auth) @@ -102,7 +102,7 @@ shared_ptr service::getAuthenticator() } -void service::setAuthenticator(shared_ptr auth) +void service::setAuthenticator(const shared_ptr & auth) { m_auth = auth; } @@ -110,7 +110,7 @@ void service::setAuthenticator(shared_ptr auth) #if VMIME_HAVE_TLS_SUPPORT -void service::setCertificateVerifier(shared_ptr cv) +void service::setCertificateVerifier(const shared_ptr & cv) { m_certVerifier = cv; } @@ -124,7 +124,7 @@ shared_ptr service::getCertificateVerifier #endif // VMIME_HAVE_TLS_SUPPORT -void service::setSocketFactory(shared_ptr sf) +void service::setSocketFactory(const shared_ptr & sf) { m_socketFactory = sf; } @@ -136,7 +136,7 @@ shared_ptr service::getSocketFactory() } -void service::setTracerFactory(shared_ptr tf) +void service::setTracerFactory(const shared_ptr & tf) { m_tracerFactory = tf; } @@ -148,7 +148,7 @@ shared_ptr service::getTracerFactory() } -void service::setTimeoutHandlerFactory(shared_ptr thf) +void service::setTimeoutHandlerFactory(const shared_ptr & thf) { m_toHandlerFactory = thf; } diff --git a/src/vmime/net/service.hpp b/src/vmime/net/service.hpp index 8d144aec..1fa120d3 100644 --- a/src/vmime/net/service.hpp +++ b/src/vmime/net/service.hpp @@ -60,7 +60,7 @@ class VMIME_EXPORT service : public object, public enable_shared_from_this sess, const serviceInfos& infos, shared_ptr auth); + service(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth); public: @@ -139,14 +139,14 @@ public: * * @param auth authenticator object */ - void setAuthenticator(shared_ptr auth); + void setAuthenticator(const shared_ptr & auth); #if VMIME_HAVE_TLS_SUPPORT /** Set the object responsible for verifying certificates when * using secured connections (TLS/SSL). */ - void setCertificateVerifier(shared_ptr cv); + void setCertificateVerifier(const shared_ptr & cv); /** Get the object responsible for verifying certificates when * using secured connections (TLS/SSL). @@ -160,7 +160,7 @@ public: * * @param sf socket factory */ - void setSocketFactory(shared_ptr sf); + void setSocketFactory(const shared_ptr & sf); /** Return the factory used to create socket objects for this * service. @@ -175,7 +175,7 @@ public: * * @param thf timeoutHandler factory */ - void setTimeoutHandlerFactory(shared_ptr thf); + void setTimeoutHandlerFactory(const shared_ptr & thf); /** Return the factory used to create timeoutHandler objects for * this service. @@ -185,7 +185,7 @@ public: shared_ptr getTimeoutHandlerFactory(); - void setTracerFactory(shared_ptr tf); + void setTracerFactory(const shared_ptr & tf); shared_ptr getTracerFactory(); diff --git a/src/vmime/net/serviceFactory.cpp b/src/vmime/net/serviceFactory.cpp index b6f90eb2..dc129c63 100644 --- a/src/vmime/net/serviceFactory.cpp +++ b/src/vmime/net/serviceFactory.cpp @@ -57,8 +57,8 @@ shared_ptr serviceFactory::getInstance() shared_ptr serviceFactory::create - (shared_ptr sess, const string& protocol, - shared_ptr auth) + (const shared_ptr & sess, const string& protocol, + const shared_ptr & auth) { shared_ptr rserv = getServiceByProtocol(protocol); @@ -70,8 +70,8 @@ shared_ptr serviceFactory::create shared_ptr serviceFactory::create - (shared_ptr sess, const utility::url& u, - shared_ptr auth) + (const shared_ptr & sess, const utility::url& u, + const shared_ptr & auth) { shared_ptr serv = create(sess, u.getProtocol(), auth); @@ -136,7 +136,7 @@ const std::vector > servic } -void serviceFactory::registerService(shared_ptr reg) +void serviceFactory::registerService(const shared_ptr & reg) { m_services.push_back(reg); } diff --git a/src/vmime/net/serviceFactory.hpp b/src/vmime/net/serviceFactory.hpp index 9295b345..cb778b91 100644 --- a/src/vmime/net/serviceFactory.hpp +++ b/src/vmime/net/serviceFactory.hpp @@ -81,8 +81,8 @@ public: public: virtual shared_ptr create - (shared_ptr sess, - shared_ptr auth) const = 0; + (const shared_ptr & sess, + const shared_ptr & auth) const = 0; virtual int getType() const = 0; virtual const string& getName() const = 0; @@ -94,7 +94,7 @@ public: * * @param reg service registration infos */ - void registerService(shared_ptr reg); + void registerService(const shared_ptr & reg); /** Create a new service instance from a protocol name. * @@ -105,9 +105,9 @@ public: * is registered for this protocol */ shared_ptr create - (shared_ptr sess, + (const shared_ptr & sess, const string& protocol, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Create a new service instance from a URL. * @@ -119,9 +119,9 @@ public: * is registered for this protocol */ shared_ptr create - (shared_ptr sess, + (const shared_ptr & sess, const utility::url& u, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Return information about a registered protocol. * diff --git a/src/vmime/net/serviceInfos.cpp b/src/vmime/net/serviceInfos.cpp index c5d0124a..b3fa7d03 100644 --- a/src/vmime/net/serviceInfos.cpp +++ b/src/vmime/net/serviceInfos.cpp @@ -88,7 +88,7 @@ serviceInfos::~serviceInfos() } -bool serviceInfos::hasProperty(shared_ptr s, const property& p) const +bool serviceInfos::hasProperty(const shared_ptr & s, const property& p) const { return s->getProperties().hasProperty(getPropertyPrefix() + p.getName()); } diff --git a/src/vmime/net/serviceInfos.hpp b/src/vmime/net/serviceInfos.hpp index 5c3909b2..63261867 100644 --- a/src/vmime/net/serviceInfos.hpp +++ b/src/vmime/net/serviceInfos.hpp @@ -221,7 +221,7 @@ public: * @return value of the property */ template - const TYPE getPropertyValue(shared_ptr s, const property& p) const + const TYPE getPropertyValue(const shared_ptr & s, const property& p) const { if (p.getFlags() & property::FLAG_REQUIRED) return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue (); @@ -237,7 +237,7 @@ public: * @param p property to test * @return true if the property is set, false otherwise */ - bool hasProperty(shared_ptr s, const property& p) const; + bool hasProperty(const shared_ptr & s, const property& p) const; }; diff --git a/src/vmime/net/serviceRegistration.inl b/src/vmime/net/serviceRegistration.inl index 2366fe01..5a897594 100644 --- a/src/vmime/net/serviceRegistration.inl +++ b/src/vmime/net/serviceRegistration.inl @@ -42,8 +42,8 @@ public: } shared_ptr create - (shared_ptr sess, - shared_ptr auth) const + (const shared_ptr & sess, + const shared_ptr & auth) const { return make_shared (sess, auth); } diff --git a/src/vmime/net/session.cpp b/src/vmime/net/session.cpp index 7e335899..9da2fc69 100644 --- a/src/vmime/net/session.cpp +++ b/src/vmime/net/session.cpp @@ -78,14 +78,14 @@ shared_ptr session::create(const propertySet& props) } -shared_ptr session::getTransport(shared_ptr auth) +shared_ptr session::getTransport(const shared_ptr & auth) { return (getTransport(m_props["transport.protocol"], auth)); } shared_ptr session::getTransport - (const string& protocol, shared_ptr auth) + (const string& protocol, const shared_ptr & auth) { shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, protocol, auth); @@ -98,7 +98,7 @@ shared_ptr session::getTransport shared_ptr session::getTransport - (const utility::url& url, shared_ptr auth) + (const utility::url& url, const shared_ptr & auth) { shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, url, auth); @@ -110,14 +110,14 @@ shared_ptr session::getTransport } -shared_ptr session::getStore(shared_ptr auth) +shared_ptr session::getStore(const shared_ptr & auth) { return (getStore(m_props["store.protocol"], auth)); } shared_ptr session::getStore - (const string& protocol, shared_ptr auth) + (const string& protocol, const shared_ptr & auth) { shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, protocol, auth); @@ -130,7 +130,7 @@ shared_ptr session::getStore shared_ptr session::getStore - (const utility::url& url, shared_ptr auth) + (const utility::url& url, const shared_ptr & auth) { shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, url, auth); @@ -156,7 +156,7 @@ propertySet& session::getProperties() #if VMIME_HAVE_TLS_SUPPORT -void session::setTLSProperties(shared_ptr tlsProps) +void session::setTLSProperties(const shared_ptr & tlsProps) { m_tlsProps = make_shared (*tlsProps); } diff --git a/src/vmime/net/session.hpp b/src/vmime/net/session.hpp index 3165e1ce..75858ef2 100644 --- a/src/vmime/net/session.hpp +++ b/src/vmime/net/session.hpp @@ -85,7 +85,7 @@ public: * protocol or is not a transport protocol */ shared_ptr getTransport - (shared_ptr auth = null); + (const shared_ptr & auth = null); /** Return a transport service instance for the specified protocol. * @@ -98,7 +98,7 @@ public: */ shared_ptr getTransport (const string& protocol, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Return a transport service instance for the specified URL. * @@ -111,7 +111,7 @@ public: */ shared_ptr getTransport (const utility::url& url, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Return a transport service instance for the protocol specified * in the session properties. @@ -124,7 +124,7 @@ public: * @return a new store service, or NULL if no service is registered for this * protocol or is not a store protocol */ - shared_ptr getStore(shared_ptr auth = null); + shared_ptr getStore(const shared_ptr & auth = null); /** Return a store service instance for the specified protocol. * @@ -137,7 +137,7 @@ public: */ shared_ptr getStore (const string& protocol, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Return a store service instance for the specified URL. * @@ -150,7 +150,7 @@ public: */ shared_ptr getStore (const utility::url& url, - shared_ptr auth = null); + const shared_ptr & auth = null); /** Properties for the session and for the services. */ @@ -166,7 +166,7 @@ public: * * @param tlsProps SSL/TLS properties */ - void setTLSProperties(shared_ptr tlsProps); + void setTLSProperties(const shared_ptr & tlsProps); /** Get properties for SSL/TLS secured connections in this session. * diff --git a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp index f6ecc54d..d1d58e4c 100644 --- a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp @@ -41,7 +41,7 @@ namespace smtp { SMTPChunkingOutputStreamAdapter::SMTPChunkingOutputStreamAdapter - (shared_ptr conn, const size_t size, utility::progressListener* progress) + (const shared_ptr & conn, const size_t size, utility::progressListener* progress) : m_connection(conn), m_bufferSize(0), m_chunkCount(0), m_totalSize(size), m_totalSent(0), m_progress(progress) { diff --git a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp index 56d72fb1..7bda1e73 100644 --- a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp @@ -49,7 +49,7 @@ class VMIME_EXPORT SMTPChunkingOutputStreamAdapter : public utility::outputStrea { public: - SMTPChunkingOutputStreamAdapter(shared_ptr conn, + SMTPChunkingOutputStreamAdapter(const shared_ptr & conn, const size_t size, utility::progressListener* progress); void flush(); diff --git a/src/vmime/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index 27c8ec1b..acf59830 100644 --- a/src/vmime/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp @@ -221,7 +221,7 @@ const string SMTPCommand::getTraceText() const } -void SMTPCommand::writeToSocket(shared_ptr sok, shared_ptr tr) +void SMTPCommand::writeToSocket(const shared_ptr & sok, shared_ptr tr) { sok->send(m_text + "\r\n"); diff --git a/src/vmime/net/smtp/SMTPCommand.hpp b/src/vmime/net/smtp/SMTPCommand.hpp index 7c00d156..bb52dbc4 100644 --- a/src/vmime/net/smtp/SMTPCommand.hpp +++ b/src/vmime/net/smtp/SMTPCommand.hpp @@ -84,7 +84,7 @@ public: * @param sok socket to which the command will be written * @param tr tracer */ - virtual void writeToSocket(shared_ptr sok, shared_ptr tr); + virtual void writeToSocket(const shared_ptr & sok, shared_ptr tr); /** Returns the full text of the command, including command name * and parameters (if any). diff --git a/src/vmime/net/smtp/SMTPCommandSet.cpp b/src/vmime/net/smtp/SMTPCommandSet.cpp index 85f58fed..425b3535 100644 --- a/src/vmime/net/smtp/SMTPCommandSet.cpp +++ b/src/vmime/net/smtp/SMTPCommandSet.cpp @@ -55,7 +55,7 @@ shared_ptr SMTPCommandSet::create(const bool pipeline) } -void SMTPCommandSet::addCommand(shared_ptr cmd) +void SMTPCommandSet::addCommand(const shared_ptr & cmd) { if (m_started) { @@ -67,7 +67,7 @@ void SMTPCommandSet::addCommand(shared_ptr cmd) } -void SMTPCommandSet::writeToSocket(shared_ptr sok, shared_ptr tr) +void SMTPCommandSet::writeToSocket(const shared_ptr & sok, const shared_ptr & tr) { if (m_pipeline) { diff --git a/src/vmime/net/smtp/SMTPCommandSet.hpp b/src/vmime/net/smtp/SMTPCommandSet.hpp index 83c7fe46..af69366e 100644 --- a/src/vmime/net/smtp/SMTPCommandSet.hpp +++ b/src/vmime/net/smtp/SMTPCommandSet.hpp @@ -61,7 +61,7 @@ public: * * @param cmd command to add */ - void addCommand(shared_ptr cmd); + void addCommand(const shared_ptr & cmd); /** Tests whether all commands have been sent. * @@ -78,7 +78,7 @@ public: shared_ptr getLastCommandSent() const; - void writeToSocket(shared_ptr sok, shared_ptr tr); + void writeToSocket(const shared_ptr & sok, const shared_ptr & tr); const string getText() const; const string getTraceText() const; diff --git a/src/vmime/net/smtp/SMTPConnection.cpp b/src/vmime/net/smtp/SMTPConnection.cpp index 8709efe4..cad107cb 100644 --- a/src/vmime/net/smtp/SMTPConnection.cpp +++ b/src/vmime/net/smtp/SMTPConnection.cpp @@ -67,7 +67,7 @@ namespace smtp { -SMTPConnection::SMTPConnection(shared_ptr transport, shared_ptr auth) +SMTPConnection::SMTPConnection(const shared_ptr & transport, const shared_ptr & auth) : m_transport(transport), m_auth(auth), m_socket(null), m_timeoutHandler(null), m_authenticated(false), m_secured(false), m_extendedSMTP(false) { @@ -605,7 +605,7 @@ void SMTPConnection::internalDisconnect() } -void SMTPConnection::sendRequest(shared_ptr cmd) +void SMTPConnection::sendRequest(const shared_ptr & cmd) { cmd->writeToSocket(m_socket, m_tracer); } diff --git a/src/vmime/net/smtp/SMTPConnection.hpp b/src/vmime/net/smtp/SMTPConnection.hpp index c7614920..50f5daf2 100644 --- a/src/vmime/net/smtp/SMTPConnection.hpp +++ b/src/vmime/net/smtp/SMTPConnection.hpp @@ -65,7 +65,7 @@ class VMIME_EXPORT SMTPConnection : public object { public: - SMTPConnection(shared_ptr transport, shared_ptr auth); + SMTPConnection(const shared_ptr & transport, const shared_ptr & auth); virtual ~SMTPConnection(); @@ -83,7 +83,7 @@ public: virtual shared_ptr getSession(); virtual shared_ptr getTracer(); - void sendRequest(shared_ptr cmd); + void sendRequest(const shared_ptr & cmd); shared_ptr readResponse(); bool hasExtension(const std::string& extName, std::vector * params = NULL) const; diff --git a/src/vmime/net/smtp/SMTPResponse.cpp b/src/vmime/net/smtp/SMTPResponse.cpp index b4b2c542..d1c25cf8 100644 --- a/src/vmime/net/smtp/SMTPResponse.cpp +++ b/src/vmime/net/smtp/SMTPResponse.cpp @@ -45,8 +45,8 @@ namespace smtp { SMTPResponse::SMTPResponse - (shared_ptr tr, shared_ptr sok, - shared_ptr toh, const state& st) + (const shared_ptr & tr, const shared_ptr & sok, + const shared_ptr & toh, const state& st) : m_socket(sok), m_timeoutHandler(toh), m_tracer(tr), m_responseBuffer(st.responseBuffer), m_responseContinues(false) { @@ -98,8 +98,8 @@ const string SMTPResponse::getText() const // static shared_ptr SMTPResponse::readResponse - (shared_ptr tr, shared_ptr sok, - shared_ptr toh, const state& st) + (const shared_ptr & tr, const shared_ptr & sok, + const shared_ptr & toh, const state& st) { shared_ptr resp = shared_ptr (new SMTPResponse(tr, sok, toh, st)); diff --git a/src/vmime/net/smtp/SMTPResponse.hpp b/src/vmime/net/smtp/SMTPResponse.hpp index 4d88b6b5..fa19a1db 100644 --- a/src/vmime/net/smtp/SMTPResponse.hpp +++ b/src/vmime/net/smtp/SMTPResponse.hpp @@ -105,8 +105,8 @@ public: * has been received within the granted time */ static shared_ptr readResponse - (shared_ptr tr, shared_ptr sok, - shared_ptr toh, const state& st); + (const shared_ptr & tr, const shared_ptr & sok, + const shared_ptr & toh, const state& st); /** Return the SMTP response code. * @@ -154,7 +154,7 @@ public: private: - SMTPResponse(shared_ptr tr, shared_ptr sok, shared_ptr toh, const state& st); + SMTPResponse(const shared_ptr & tr, const shared_ptr & sok, const shared_ptr & toh, const state& st); SMTPResponse(const SMTPResponse&); void readResponse(); diff --git a/src/vmime/net/smtp/SMTPSTransport.cpp b/src/vmime/net/smtp/SMTPSTransport.cpp index ab64d49d..1a8a0804 100644 --- a/src/vmime/net/smtp/SMTPSTransport.cpp +++ b/src/vmime/net/smtp/SMTPSTransport.cpp @@ -35,7 +35,7 @@ namespace net { namespace smtp { -SMTPSTransport::SMTPSTransport(shared_ptr sess, shared_ptr auth) +SMTPSTransport::SMTPSTransport(const shared_ptr & sess, const shared_ptr & auth) : SMTPTransport(sess, auth, true) { } diff --git a/src/vmime/net/smtp/SMTPSTransport.hpp b/src/vmime/net/smtp/SMTPSTransport.hpp index 7782f711..52dce1f2 100644 --- a/src/vmime/net/smtp/SMTPSTransport.hpp +++ b/src/vmime/net/smtp/SMTPSTransport.hpp @@ -46,7 +46,7 @@ class VMIME_EXPORT SMTPSTransport : public SMTPTransport { public: - SMTPSTransport(shared_ptr sess, shared_ptr auth); + SMTPSTransport(const shared_ptr & sess, const shared_ptr & auth); ~SMTPSTransport(); const string getProtocolName() const; diff --git a/src/vmime/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index 25eb72a7..27afcf6f 100644 --- a/src/vmime/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp @@ -51,7 +51,7 @@ namespace net { namespace smtp { -SMTPTransport::SMTPTransport(shared_ptr sess, shared_ptr auth, const bool secured) +SMTPTransport::SMTPTransport(const shared_ptr & sess, const shared_ptr & auth, const bool secured) : transport(sess, getInfosInstance(), auth), m_isSMTPS(secured), m_needReset(false) { } @@ -377,7 +377,7 @@ void SMTPTransport::send void SMTPTransport::send - (shared_ptr msg, const mailbox& expeditor, const mailboxList& recipients, + (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, utility::progressListener* progress, const mailbox& sender) { if (!isConnected()) diff --git a/src/vmime/net/smtp/SMTPTransport.hpp b/src/vmime/net/smtp/SMTPTransport.hpp index 7b266d3d..a5f15ca6 100644 --- a/src/vmime/net/smtp/SMTPTransport.hpp +++ b/src/vmime/net/smtp/SMTPTransport.hpp @@ -54,7 +54,7 @@ class VMIME_EXPORT SMTPTransport : public transport { public: - SMTPTransport(shared_ptr sess, shared_ptr auth, const bool secured = false); + SMTPTransport(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); ~SMTPTransport(); const string getProtocolName() const; @@ -77,7 +77,7 @@ public: const mailbox& sender = mailbox()); void send - (shared_ptr msg, + (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, utility::progressListener* progress = NULL, diff --git a/src/vmime/net/socket.hpp b/src/vmime/net/socket.hpp index 2de83dd1..4de45ca9 100644 --- a/src/vmime/net/socket.hpp +++ b/src/vmime/net/socket.hpp @@ -175,7 +175,7 @@ public: * * @param tracer tracer to use */ - virtual void setTracer(shared_ptr tracer) = 0; + virtual void setTracer(const shared_ptr & tracer) = 0; /** Return the tracer used by this socket. * @@ -213,7 +213,7 @@ public: * @param th timeout handler * @return a new socket */ - virtual shared_ptr create(shared_ptr th) = 0; + virtual shared_ptr create(const shared_ptr & th) = 0; }; diff --git a/src/vmime/net/store.hpp b/src/vmime/net/store.hpp index 37dcadbc..dfeb9a53 100644 --- a/src/vmime/net/store.hpp +++ b/src/vmime/net/store.hpp @@ -47,7 +47,7 @@ class VMIME_EXPORT store : public service { protected: - store(shared_ptr sess, const serviceInfos& infos, shared_ptr auth) + store(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth) : service(sess, infos, auth) { } public: diff --git a/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp index 4856e9af..45b9527e 100644 --- a/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp @@ -38,7 +38,7 @@ namespace tls { TLSSecuredConnectionInfos::TLSSecuredConnectionInfos (const string& host, const port_t port, - shared_ptr tlsSession, shared_ptr tlsSocket) + const shared_ptr & tlsSession, const shared_ptr & tlsSocket) : m_host(host), m_port(port), m_tlsSession(tlsSession), m_tlsSocket(tlsSocket) { diff --git a/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp index e552d6f9..19e7a064 100644 --- a/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp @@ -52,7 +52,7 @@ class VMIME_EXPORT TLSSecuredConnectionInfos : public securedConnectionInfos public: TLSSecuredConnectionInfos(const string& host, const port_t port, - shared_ptr tlsSession, shared_ptr tlsSocket); + const shared_ptr & tlsSession, const shared_ptr & tlsSocket); const string getHost() const; port_t getPort() const; diff --git a/src/vmime/net/tls/TLSSession.hpp b/src/vmime/net/tls/TLSSession.hpp index 8951ffa4..83a1623c 100644 --- a/src/vmime/net/tls/TLSSession.hpp +++ b/src/vmime/net/tls/TLSSession.hpp @@ -57,7 +57,7 @@ public: * @param props TLS properties for this session * @return a new TLS session */ - static shared_ptr create(shared_ptr cv, shared_ptr props); + static shared_ptr create(const shared_ptr & cv, const shared_ptr & props); /** Create a new socket that adds a TLS security layer around * an existing socket. You should create only one socket @@ -66,7 +66,7 @@ public: * @param sok socket to wrap * @return TLS socket wrapper */ - virtual shared_ptr getSocket(shared_ptr sok) = 0; + virtual shared_ptr getSocket(const shared_ptr & sok) = 0; /** Get the object responsible for verifying certificates when * using secured connections (TLS/SSL). diff --git a/src/vmime/net/tls/TLSSocket.hpp b/src/vmime/net/tls/TLSSocket.hpp index be27d1d0..75b80116 100644 --- a/src/vmime/net/tls/TLSSocket.hpp +++ b/src/vmime/net/tls/TLSSocket.hpp @@ -59,7 +59,7 @@ public: * @param session TLS session * @param sok socket to wrap */ - static shared_ptr wrap(shared_ptr session, shared_ptr sok); + static shared_ptr wrap(const shared_ptr & session, const shared_ptr & sok); /** Starts a TLS handshake on this connection. * diff --git a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp index 2a6450eb..dccfb5ec 100644 --- a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp @@ -134,13 +134,13 @@ static TLSGlobal g_gnutlsGlobal; // static -shared_ptr TLSSession::create(shared_ptr cv, shared_ptr props) +shared_ptr TLSSession::create(const shared_ptr & cv, const shared_ptr & props) { return make_shared (cv, props); } -TLSSession_GnuTLS::TLSSession_GnuTLS(shared_ptr cv, shared_ptr props) +TLSSession_GnuTLS::TLSSession_GnuTLS(const shared_ptr & cv, const shared_ptr & props) : m_certVerifier(cv), m_props(props) { int res; @@ -274,7 +274,7 @@ TLSSession_GnuTLS::~TLSSession_GnuTLS() } -shared_ptr TLSSession_GnuTLS::getSocket(shared_ptr sok) +shared_ptr TLSSession_GnuTLS::getSocket(const shared_ptr & sok) { return TLSSocket::wrap(dynamicCast (shared_from_this()), sok); } diff --git a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp index 14172ee0..dd096ff3 100644 --- a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp @@ -52,11 +52,11 @@ class TLSSession_GnuTLS : public TLSSession public: - TLSSession_GnuTLS(shared_ptr cv, shared_ptr props); + TLSSession_GnuTLS(const shared_ptr & cv, const shared_ptr & props); ~TLSSession_GnuTLS(); - shared_ptr getSocket(shared_ptr sok); + shared_ptr getSocket(const shared_ptr & sok); shared_ptr getCertificateVerifier(); diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 16dabb66..31753590 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp @@ -50,14 +50,14 @@ namespace tls { // static -shared_ptr TLSSocket::wrap(shared_ptr session, shared_ptr sok) +shared_ptr TLSSocket::wrap(const shared_ptr & session, const shared_ptr & sok) { return make_shared (dynamicCast (session), sok); } -TLSSocket_GnuTLS::TLSSocket_GnuTLS(shared_ptr session, shared_ptr sok) +TLSSocket_GnuTLS::TLSSocket_GnuTLS(const shared_ptr & session, const shared_ptr & sok) : m_session(session), m_wrapped(sok), m_connected(false), m_ex(NULL), m_status(0), m_errno(0) { @@ -143,7 +143,7 @@ shared_ptr TLSSocket_GnuTLS::getTimeoutHandler() } -void TLSSocket_GnuTLS::setTracer(shared_ptr tracer) +void TLSSocket_GnuTLS::setTracer(const shared_ptr & tracer) { m_wrapped->setTracer(tracer); } diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp index 931cb993..a1d78e99 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp @@ -50,7 +50,7 @@ class TLSSocket_GnuTLS : public TLSSocket { public: - TLSSocket_GnuTLS(shared_ptr session, shared_ptr sok); + TLSSocket_GnuTLS(const shared_ptr & session, const shared_ptr & sok); ~TLSSocket_GnuTLS(); @@ -83,7 +83,7 @@ public: shared_ptr getTimeoutHandler(); - void setTracer(shared_ptr tracer); + void setTracer(const shared_ptr & tracer); shared_ptr getTracer(); private: diff --git a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp index 7892de65..961f6517 100644 --- a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp @@ -46,13 +46,13 @@ static OpenSSLInitializer::autoInitializer openSSLInitializer; // static -shared_ptr TLSSession::create(shared_ptr cv, shared_ptr props) +shared_ptr TLSSession::create(const shared_ptr & cv, const shared_ptr & props) { return make_shared (cv, props); } -TLSSession_OpenSSL::TLSSession_OpenSSL(shared_ptr cv, shared_ptr props) +TLSSession_OpenSSL::TLSSession_OpenSSL(const shared_ptr & cv, const shared_ptr & props) : m_sslctx(0), m_certVerifier(cv), m_props(props) { m_sslctx = SSL_CTX_new(SSLv23_client_method()); @@ -76,7 +76,7 @@ TLSSession_OpenSSL::~TLSSession_OpenSSL() } -shared_ptr TLSSession_OpenSSL::getSocket(shared_ptr sok) +shared_ptr TLSSession_OpenSSL::getSocket(const shared_ptr & sok) { return TLSSocket::wrap(dynamicCast (shared_from_this()), sok); } diff --git a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp index 5a2b60a8..c5c5da39 100644 --- a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp @@ -55,11 +55,11 @@ class TLSSession_OpenSSL : public TLSSession public: - TLSSession_OpenSSL(const shared_ptr cv, shared_ptr props); + TLSSession_OpenSSL(const shared_ptr & cv, const shared_ptr & props); ~TLSSession_OpenSSL(); - shared_ptr getSocket(shared_ptr sok); + shared_ptr getSocket(const shared_ptr & sok); shared_ptr getCertificateVerifier(); diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp index 827dcf1b..afc7e514 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp @@ -87,14 +87,14 @@ BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = // static -shared_ptr TLSSocket::wrap(shared_ptr session, shared_ptr sok) +shared_ptr TLSSocket::wrap(const shared_ptr & session, const shared_ptr & sok) { return make_shared (dynamicCast (session), sok); } -TLSSocket_OpenSSL::TLSSocket_OpenSSL(shared_ptr session, shared_ptr sok) +TLSSocket_OpenSSL::TLSSocket_OpenSSL(const shared_ptr & session, const shared_ptr & sok) : m_session(session), m_wrapped(sok), m_connected(false), m_ssl(0), m_status(0), m_ex() { } @@ -242,7 +242,7 @@ shared_ptr TLSSocket_OpenSSL::getTimeoutHandler() } -void TLSSocket_OpenSSL::setTracer(shared_ptr tracer) +void TLSSocket_OpenSSL::setTracer(const shared_ptr & tracer) { m_wrapped->setTracer(tracer); } diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp index 34324b8c..9f395051 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp @@ -54,7 +54,7 @@ class TLSSocket_OpenSSL : public TLSSocket { public: - TLSSocket_OpenSSL(shared_ptr session, shared_ptr sok); + TLSSocket_OpenSSL(const shared_ptr & session, const shared_ptr & sok); ~TLSSocket_OpenSSL(); @@ -87,7 +87,7 @@ public: shared_ptr getTimeoutHandler(); - void setTracer(shared_ptr tracer); + void setTracer(const shared_ptr & tracer); shared_ptr getTracer(); private: diff --git a/src/vmime/net/tracer.hpp b/src/vmime/net/tracer.hpp index e30c823c..853455a3 100644 --- a/src/vmime/net/tracer.hpp +++ b/src/vmime/net/tracer.hpp @@ -96,7 +96,7 @@ public: * different connections used by a service * @return a new tracer */ - virtual shared_ptr create(shared_ptr serv, const int connectionId) = 0; + virtual shared_ptr create(const shared_ptr & serv, const int connectionId) = 0; }; diff --git a/src/vmime/net/transport.cpp b/src/vmime/net/transport.cpp index dd7281d0..1b69995c 100644 --- a/src/vmime/net/transport.cpp +++ b/src/vmime/net/transport.cpp @@ -43,13 +43,13 @@ namespace vmime { namespace net { -transport::transport(shared_ptr sess, const serviceInfos& infos, shared_ptr auth) +transport::transport(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth) : service(sess, infos, auth) { } -shared_ptr transport::processHeaderField(shared_ptr field) +shared_ptr transport::processHeaderField(const shared_ptr & field) { if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::BCC)) { @@ -77,7 +77,7 @@ shared_ptr transport::processHeaderField(shared_ptr } -void transport::processHeader(shared_ptr
header) +void transport::processHeader(const shared_ptr
& header) { if (header->getFieldCount() == 0) return; @@ -122,7 +122,7 @@ static void extractMailboxes } -void transport::send(shared_ptr msg, utility::progressListener* progress) +void transport::send(const shared_ptr & msg, utility::progressListener* progress) { // Extract expeditor shared_ptr fromMbox = @@ -179,8 +179,8 @@ void transport::send(shared_ptr msg, utility::progressListener* // Revert it back to original header after. struct XChangeMsgHeader { - XChangeMsgHeader(shared_ptr _msg, - shared_ptr _hdr) + XChangeMsgHeader(const shared_ptr & _msg, + const shared_ptr & _hdr) : msg(_msg), hdr(msg->getHeader()) { // Set new header @@ -204,7 +204,7 @@ void transport::send(shared_ptr msg, utility::progressListener* void transport::send - (shared_ptr msg, const mailbox& expeditor, const mailboxList& recipients, + (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, utility::progressListener* progress, const mailbox& sender) { // Generate the message, "stream" it and delegate the sending diff --git a/src/vmime/net/transport.hpp b/src/vmime/net/transport.hpp index 6c405cbb..a54f041e 100644 --- a/src/vmime/net/transport.hpp +++ b/src/vmime/net/transport.hpp @@ -56,7 +56,7 @@ class VMIME_EXPORT transport : public service { protected: - transport(shared_ptr sess, const serviceInfos& infos, shared_ptr auth); + transport(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth); public: @@ -67,7 +67,7 @@ public: * @param msg message to send * @param progress progress listener, or NULL if not used */ - virtual void send(shared_ptr msg, utility::progressListener* progress = NULL); + virtual void send(const shared_ptr & msg, utility::progressListener* progress = NULL); /** Send a message over this transport service. * @@ -97,7 +97,7 @@ public: * @param sender envelope sender (if empty, expeditor will be used) */ virtual void send - (shared_ptr msg, + (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, utility::progressListener* progress = NULL, @@ -115,7 +115,7 @@ protected: * if the field is to be replaced, or a reference to the same headerField * that was passed if the field should be left as is */ - shared_ptr processHeaderField(shared_ptr field); + shared_ptr processHeaderField(const shared_ptr & field); /** Prepares the header before transmitting the message. * Removes headers that should not be present (eg. "Bcc", "Return-Path"), @@ -124,7 +124,7 @@ protected: * * @param header headers to process */ - void processHeader(shared_ptr
header); + void processHeader(const shared_ptr
& header); }; diff --git a/src/vmime/parameterizedHeaderField.cpp b/src/vmime/parameterizedHeaderField.cpp index c299ff65..0d90692b 100644 --- a/src/vmime/parameterizedHeaderField.cpp +++ b/src/vmime/parameterizedHeaderField.cpp @@ -457,13 +457,13 @@ shared_ptr parameterizedHeaderField::getParameter(const string& para } -void parameterizedHeaderField::appendParameter(shared_ptr param) +void parameterizedHeaderField::appendParameter(const shared_ptr & param) { m_params.push_back(param); } -void parameterizedHeaderField::insertParameterBefore(shared_ptr beforeParam, shared_ptr param) +void parameterizedHeaderField::insertParameterBefore(const shared_ptr & beforeParam, const shared_ptr & param) { const std::vector >::iterator it = std::find (m_params.begin(), m_params.end(), beforeParam); @@ -475,7 +475,7 @@ void parameterizedHeaderField::insertParameterBefore(shared_ptr befo } -void parameterizedHeaderField::insertParameterBefore(const size_t pos, shared_ptr param) +void parameterizedHeaderField::insertParameterBefore(const size_t pos, const shared_ptr & param) { if (pos >= m_params.size()) throw std::out_of_range("Invalid position"); @@ -484,7 +484,7 @@ void parameterizedHeaderField::insertParameterBefore(const size_t pos, shared_pt } -void parameterizedHeaderField::insertParameterAfter(shared_ptr afterParam, shared_ptr param) +void parameterizedHeaderField::insertParameterAfter(const shared_ptr & afterParam, const shared_ptr & param) { const std::vector >::iterator it = std::find (m_params.begin(), m_params.end(), afterParam); @@ -496,7 +496,7 @@ void parameterizedHeaderField::insertParameterAfter(shared_ptr after } -void parameterizedHeaderField::insertParameterAfter(const size_t pos, shared_ptr param) +void parameterizedHeaderField::insertParameterAfter(const size_t pos, const shared_ptr & param) { if (pos >= m_params.size()) throw std::out_of_range("Invalid position"); @@ -505,7 +505,7 @@ void parameterizedHeaderField::insertParameterAfter(const size_t pos, shared_ptr } -void parameterizedHeaderField::removeParameter(shared_ptr param) +void parameterizedHeaderField::removeParameter(const shared_ptr & param) { const std::vector >::iterator it = std::find (m_params.begin(), m_params.end(), param); diff --git a/src/vmime/parameterizedHeaderField.hpp b/src/vmime/parameterizedHeaderField.hpp index 47c53562..113df16d 100644 --- a/src/vmime/parameterizedHeaderField.hpp +++ b/src/vmime/parameterizedHeaderField.hpp @@ -89,7 +89,7 @@ public: * * @param param parameter to append */ - void appendParameter(shared_ptr param); + void appendParameter(const shared_ptr & param); /** Insert a new parameter before the specified parameter. * @@ -97,7 +97,7 @@ public: * @param param parameter to insert * @throw std::out_of_range if the parameter is not in the list */ - void insertParameterBefore(shared_ptr beforeParam, shared_ptr param); + void insertParameterBefore(const shared_ptr & beforeParam, const shared_ptr & param); /** Insert a new parameter before the specified position. * @@ -106,7 +106,7 @@ public: * @param param parameter to insert * @throw std::out_of_range if the position is out of range */ - void insertParameterBefore(const size_t pos, shared_ptr param); + void insertParameterBefore(const size_t pos, const shared_ptr & param); /** Insert a new parameter after the specified parameter. * @@ -114,7 +114,7 @@ public: * @param param parameter to insert * @throw std::out_of_range if the parameter is not in the list */ - void insertParameterAfter(shared_ptr afterParam, shared_ptr param); + void insertParameterAfter(const shared_ptr & afterParam, const shared_ptr & param); /** Insert a new parameter after the specified position. * @@ -122,14 +122,14 @@ public: * @param param parameter to insert * @throw std::out_of_range if the position is out of range */ - void insertParameterAfter(const size_t pos, shared_ptr param); + void insertParameterAfter(const size_t pos, const shared_ptr & param); /** Remove the specified parameter from the list. * * @param param parameter to remove * @throw std::out_of_range if the parameter is not in the list */ - void removeParameter(shared_ptr param); + void removeParameter(const shared_ptr & param); /** Remove the parameter at the specified position. * diff --git a/src/vmime/parsedMessageAttachment.cpp b/src/vmime/parsedMessageAttachment.cpp index 242bfde0..efe4a5b2 100644 --- a/src/vmime/parsedMessageAttachment.cpp +++ b/src/vmime/parsedMessageAttachment.cpp @@ -33,7 +33,7 @@ namespace vmime { -parsedMessageAttachment::parsedMessageAttachment(shared_ptr msg) +parsedMessageAttachment::parsedMessageAttachment(const shared_ptr & msg) : m_msg(msg) { } @@ -97,7 +97,7 @@ shared_ptr parsedMessageAttachment::getMessage() const } -void parsedMessageAttachment::generateIn(shared_ptr parent) const +void parsedMessageAttachment::generateIn(const shared_ptr & parent) const { // Create and append a new part for this attachment shared_ptr part = make_shared (); diff --git a/src/vmime/parsedMessageAttachment.hpp b/src/vmime/parsedMessageAttachment.hpp index 6c96f80a..330cf869 100644 --- a/src/vmime/parsedMessageAttachment.hpp +++ b/src/vmime/parsedMessageAttachment.hpp @@ -41,7 +41,7 @@ class VMIME_EXPORT parsedMessageAttachment : public messageAttachment { public: - parsedMessageAttachment(shared_ptr msg); + parsedMessageAttachment(const shared_ptr & msg); const mediaType getType() const; const text getDescription() const; @@ -59,7 +59,7 @@ public: protected: - void generateIn(shared_ptr parent) const; + void generateIn(const shared_ptr & parent) const; private: diff --git a/src/vmime/plainTextPart.cpp b/src/vmime/plainTextPart.cpp index 7a1542d7..a9a245f4 100644 --- a/src/vmime/plainTextPart.cpp +++ b/src/vmime/plainTextPart.cpp @@ -57,7 +57,7 @@ size_t plainTextPart::getPartCount() const } -void plainTextPart::generateIn(shared_ptr /* message */, shared_ptr parent) const +void plainTextPart::generateIn(const shared_ptr & /* message */, const shared_ptr & parent) const { // Create a new part shared_ptr part = make_shared (); @@ -70,8 +70,8 @@ void plainTextPart::generateIn(shared_ptr /* message */, shared_ptr < } -void plainTextPart::parse(shared_ptr /* message */, - shared_ptr /* parent */, shared_ptr textPart) +void plainTextPart::parse(const shared_ptr & /* message */, + const shared_ptr & /* parent */, const shared_ptr & textPart) { m_text = vmime::clone(textPart->getBody()->getContents()); @@ -103,7 +103,7 @@ const shared_ptr plainTextPart::getText() const } -void plainTextPart::setText(shared_ptr text) +void plainTextPart::setText(const shared_ptr & text) { m_text = vmime::clone(text); } diff --git a/src/vmime/plainTextPart.hpp b/src/vmime/plainTextPart.hpp index 72a8a71c..8640dc48 100644 --- a/src/vmime/plainTextPart.hpp +++ b/src/vmime/plainTextPart.hpp @@ -48,12 +48,12 @@ public: void setCharset(const charset& ch); const shared_ptr getText() const; - void setText(shared_ptr text); + void setText(const shared_ptr & text); size_t getPartCount() const; - void generateIn(shared_ptr message, shared_ptr parent) const; - void parse(shared_ptr message, shared_ptr parent, shared_ptr textPart); + void generateIn(const shared_ptr & message, const shared_ptr & parent) const; + void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart); private: diff --git a/src/vmime/platforms/posix/posixChildProcess.cpp b/src/vmime/platforms/posix/posixChildProcess.cpp index 275cacfd..c498b7ca 100644 --- a/src/vmime/platforms/posix/posixChildProcess.cpp +++ b/src/vmime/platforms/posix/posixChildProcess.cpp @@ -245,7 +245,7 @@ posixChildProcess::~posixChildProcess() // Original authors: Dan Winship // Copyright 2000 Ximian, Inc. (www.ximian.com) -void posixChildProcess::start(const std::vector args, const int flags) +void posixChildProcess::start(const std::vector & args, const int flags) { if (m_started) return; diff --git a/src/vmime/platforms/posix/posixChildProcess.hpp b/src/vmime/platforms/posix/posixChildProcess.hpp index 5b9fa021..33f166f2 100644 --- a/src/vmime/platforms/posix/posixChildProcess.hpp +++ b/src/vmime/platforms/posix/posixChildProcess.hpp @@ -49,7 +49,7 @@ public: posixChildProcess(const utility::file::path& path); ~posixChildProcess(); - void start(const std::vector args, const int flags = 0); + void start(const std::vector & args, const int flags = 0); shared_ptr getStdIn(); shared_ptr getStdOut(); diff --git a/src/vmime/platforms/posix/posixSocket.cpp b/src/vmime/platforms/posix/posixSocket.cpp index 012e8842..e2bdd4b8 100644 --- a/src/vmime/platforms/posix/posixSocket.cpp +++ b/src/vmime/platforms/posix/posixSocket.cpp @@ -923,7 +923,7 @@ shared_ptr posixSocket::getTimeoutHandler() } -void posixSocket::setTracer(shared_ptr tracer) +void posixSocket::setTracer(const shared_ptr & tracer) { m_tracer = tracer; } @@ -947,7 +947,7 @@ shared_ptr posixSocketFactory::create() } -shared_ptr posixSocketFactory::create(shared_ptr th) +shared_ptr posixSocketFactory::create(const shared_ptr & th) { return make_shared (th); } diff --git a/src/vmime/platforms/posix/posixSocket.hpp b/src/vmime/platforms/posix/posixSocket.hpp index ebcb1a04..f253c17b 100644 --- a/src/vmime/platforms/posix/posixSocket.hpp +++ b/src/vmime/platforms/posix/posixSocket.hpp @@ -73,7 +73,7 @@ public: shared_ptr getTimeoutHandler(); - void setTracer(shared_ptr tracer); + void setTracer(const shared_ptr & tracer); shared_ptr getTracer(); protected: @@ -104,7 +104,7 @@ class posixSocketFactory : public vmime::net::socketFactory public: shared_ptr create(); - shared_ptr create(shared_ptr th); + shared_ptr create(const shared_ptr & th); }; diff --git a/src/vmime/platforms/windows/windowsSocket.cpp b/src/vmime/platforms/windows/windowsSocket.cpp index cb731443..2fadc36e 100644 --- a/src/vmime/platforms/windows/windowsSocket.cpp +++ b/src/vmime/platforms/windows/windowsSocket.cpp @@ -502,7 +502,7 @@ shared_ptr windowsSocket::getTimeoutHandler() } -void windowsSocket::setTracer(shared_ptr tracer) +void windowsSocket::setTracer(const shared_ptr & tracer) { m_tracer = tracer; } @@ -525,7 +525,7 @@ shared_ptr windowsSocketFactory::create() return make_shared (th); } -shared_ptr windowsSocketFactory::create(shared_ptr th) +shared_ptr windowsSocketFactory::create(const shared_ptr & th) { return make_shared (th); } diff --git a/src/vmime/platforms/windows/windowsSocket.hpp b/src/vmime/platforms/windows/windowsSocket.hpp index f2d2f550..84fbdfc0 100644 --- a/src/vmime/platforms/windows/windowsSocket.hpp +++ b/src/vmime/platforms/windows/windowsSocket.hpp @@ -59,7 +59,7 @@ public: void receive(vmime::string& buffer); size_t receiveRaw(byte_t* buffer, const size_t count); - + void send(const vmime::string& buffer); void send(const char* str); void sendRaw(const byte_t* buffer, const size_t count); @@ -75,7 +75,7 @@ public: shared_ptr getTimeoutHandler(); shared_ptr m_tracer; - void setTracer(shared_ptr tracer); + void setTracer(const shared_ptr & tracer); shared_ptr getTracer(); protected: @@ -103,7 +103,7 @@ class windowsSocketFactory : public vmime::net::socketFactory public: shared_ptr create(); - shared_ptr create(shared_ptr th); + shared_ptr create(const shared_ptr & th); }; diff --git a/src/vmime/propertySet.hpp b/src/vmime/propertySet.hpp index bf1c39bf..fb22b437 100644 --- a/src/vmime/propertySet.hpp +++ b/src/vmime/propertySet.hpp @@ -341,7 +341,7 @@ private: propFinder(const string& name) : m_name(utility::stringUtils::toLower(name)) { } - bool operator()(shared_ptr p) const + bool operator()(const shared_ptr & p) const { return (utility::stringUtils::toLower(p->getName()) == m_name); } diff --git a/src/vmime/security/authenticator.hpp b/src/vmime/security/authenticator.hpp index fc6bf5d5..c73229dd 100644 --- a/src/vmime/security/authenticator.hpp +++ b/src/vmime/security/authenticator.hpp @@ -123,7 +123,7 @@ public: * * @param serv messaging service instance */ - virtual void setService(shared_ptr serv) = 0; + virtual void setService(const shared_ptr & serv) = 0; }; diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp index d816646b..3aca9dd6 100644 --- a/src/vmime/security/cert/X509Certificate.hpp +++ b/src/vmime/security/cert/X509Certificate.hpp @@ -114,14 +114,14 @@ public: * @return true if this certificate was issued by the given issuer, * false otherwise */ - virtual bool checkIssuer(shared_ptr issuer) const = 0; + virtual bool checkIssuer(const shared_ptr & issuer) const = 0; /** Verifies this certificate against a given trusted one. * * @param caCert a certificate that is considered to be trusted one * @return true if the verification succeeded, false otherwise */ - virtual bool verify(shared_ptr caCert) const = 0; + virtual bool verify(const shared_ptr & caCert) const = 0; /** Verify certificate's subject name against the given hostname. * diff --git a/src/vmime/security/cert/certificate.hpp b/src/vmime/security/cert/certificate.hpp index 58e0638a..9d17ad8b 100644 --- a/src/vmime/security/cert/certificate.hpp +++ b/src/vmime/security/cert/certificate.hpp @@ -64,7 +64,7 @@ public: * @return true if the two certificates are the same, * false otherwise */ - virtual bool equals(shared_ptr other) const = 0; + virtual bool equals(const shared_ptr & other) const = 0; /** Returns a pointer to internal binary data for this certificate. * The actual type of data depends on the library used for TLS support. diff --git a/src/vmime/security/cert/certificateChain.cpp b/src/vmime/security/cert/certificateChain.cpp index f1154768..1731f873 100644 --- a/src/vmime/security/cert/certificateChain.cpp +++ b/src/vmime/security/cert/certificateChain.cpp @@ -41,7 +41,7 @@ size_t certificateChain::getCount() const } -shared_ptr certificateChain::getAt(const size_t index) +const shared_ptr & certificateChain::getAt(const size_t index) { return m_certs[index]; } diff --git a/src/vmime/security/cert/certificateChain.hpp b/src/vmime/security/cert/certificateChain.hpp index 38bf6254..7846a200 100644 --- a/src/vmime/security/cert/certificateChain.hpp +++ b/src/vmime/security/cert/certificateChain.hpp @@ -62,7 +62,7 @@ public: * @param index position at which to retrieve certificate * @return certificate at the specified position */ - shared_ptr getAt(const size_t index); + const shared_ptr & getAt(const size_t index); protected: diff --git a/src/vmime/security/cert/certificateException.cpp b/src/vmime/security/cert/certificateException.cpp index 9cd81055..c28a13fe 100644 --- a/src/vmime/security/cert/certificateException.cpp +++ b/src/vmime/security/cert/certificateException.cpp @@ -58,7 +58,7 @@ exception* certificateException::clone() const } -void certificateException::setCertificate(shared_ptr cert) +void certificateException::setCertificate(const shared_ptr & cert) { m_cert = cert; } diff --git a/src/vmime/security/cert/certificateException.hpp b/src/vmime/security/cert/certificateException.hpp index c6c76127..fc4ea520 100644 --- a/src/vmime/security/cert/certificateException.hpp +++ b/src/vmime/security/cert/certificateException.hpp @@ -65,7 +65,7 @@ public: * * @param cert certificate */ - void setCertificate(shared_ptr cert); + void setCertificate(const shared_ptr & cert); /** Returns the certificate on which the problem occured. * diff --git a/src/vmime/security/cert/certificateVerifier.hpp b/src/vmime/security/cert/certificateVerifier.hpp index ae1ee312..eb6ff5eb 100644 --- a/src/vmime/security/cert/certificateVerifier.hpp +++ b/src/vmime/security/cert/certificateVerifier.hpp @@ -63,7 +63,7 @@ public: * @throw serverIdentityException if the subject name of the certificate * does not match the hostname of the server */ - virtual void verify(shared_ptr chain, const string& hostname) = 0; + virtual void verify(const shared_ptr & chain, const string& hostname) = 0; }; diff --git a/src/vmime/security/cert/defaultCertificateVerifier.cpp b/src/vmime/security/cert/defaultCertificateVerifier.cpp index 6c3e1128..39391231 100644 --- a/src/vmime/security/cert/defaultCertificateVerifier.cpp +++ b/src/vmime/security/cert/defaultCertificateVerifier.cpp @@ -57,7 +57,7 @@ defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateV void defaultCertificateVerifier::verify - (shared_ptr chain, const string& hostname) + (const shared_ptr & chain, const string& hostname) { if (chain->getCount() == 0) return; @@ -72,7 +72,7 @@ void defaultCertificateVerifier::verify void defaultCertificateVerifier::verifyX509 - (shared_ptr chain, const string& hostname) + (const shared_ptr & chain, const string& hostname) { // For every certificate in the chain, verify that the certificate // has been issued by the next certificate in the chain diff --git a/src/vmime/security/cert/defaultCertificateVerifier.hpp b/src/vmime/security/cert/defaultCertificateVerifier.hpp index 8de43714..cd57c5c1 100644 --- a/src/vmime/security/cert/defaultCertificateVerifier.hpp +++ b/src/vmime/security/cert/defaultCertificateVerifier.hpp @@ -69,7 +69,7 @@ public: // Implementation of 'certificateVerifier' - void verify(shared_ptr chain, const string& hostname); + void verify(const shared_ptr & chain, const string& hostname); private: @@ -78,7 +78,7 @@ private: * @param chain list of X.509 certificates * @param hostname server hostname */ - void verifyX509(shared_ptr chain, const string& hostname); + void verifyX509(const shared_ptr & chain, const string& hostname); std::vector > m_x509RootCAs; diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp index 85cfb1de..478c1418 100644 --- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp @@ -161,7 +161,7 @@ const byteArray X509Certificate_GnuTLS::getSerialNumber() const } -bool X509Certificate_GnuTLS::checkIssuer(shared_ptr issuer_) const +bool X509Certificate_GnuTLS::checkIssuer(const shared_ptr & issuer_) const { shared_ptr issuer = dynamicCast (issuer_); @@ -171,7 +171,7 @@ bool X509Certificate_GnuTLS::checkIssuer(shared_ptr issu } -bool X509Certificate_GnuTLS::verify(shared_ptr caCert_) const +bool X509Certificate_GnuTLS::verify(const shared_ptr & caCert_) const { shared_ptr caCert = dynamicCast (caCert_); @@ -306,7 +306,7 @@ int X509Certificate_GnuTLS::getVersion() const } -bool X509Certificate_GnuTLS::equals(shared_ptr other) const +bool X509Certificate_GnuTLS::equals(const shared_ptr & other) const { shared_ptr otherX509 = dynamicCast (other); diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp index d7d72338..f06955bf 100644 --- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp @@ -57,9 +57,9 @@ public: const byteArray getSerialNumber() const; const string getIssuerString() const; - bool checkIssuer(shared_ptr issuer) const; + bool checkIssuer(const shared_ptr & issuer) const; - bool verify(shared_ptr caCert) const; + bool verify(const shared_ptr & caCert) const; bool verifyHostName (const string& hostname, @@ -75,7 +75,7 @@ public: const byteArray getEncoded() const; const string getType() const; int getVersion() const; - bool equals(shared_ptr other) const; + bool equals(const shared_ptr & other) const; void* getInternalData(); private: diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp index a05e61d4..45481861 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -285,7 +285,7 @@ const byteArray X509Certificate_OpenSSL::getSerialNumber() const } -bool X509Certificate_OpenSSL::checkIssuer(shared_ptr cert_) const +bool X509Certificate_OpenSSL::checkIssuer(const shared_ptr & cert_) const { shared_ptr cert = dynamicCast (cert_); @@ -312,7 +312,7 @@ bool X509Certificate_OpenSSL::checkIssuer(shared_ptr cer } -bool X509Certificate_OpenSSL::verify(shared_ptr caCert_) const +bool X509Certificate_OpenSSL::verify(const shared_ptr & caCert_) const { shared_ptr caCert = dynamicCast (caCert_); @@ -572,7 +572,7 @@ int X509Certificate_OpenSSL::getVersion() const } -bool X509Certificate_OpenSSL::equals(shared_ptr other) const +bool X509Certificate_OpenSSL::equals(const shared_ptr & other) const { shared_ptr otherX509 = dynamicCast (other); diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp index dbb1b03c..89b54a9a 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp @@ -60,9 +60,9 @@ public: const byteArray getSerialNumber() const; const string getIssuerString() const; - bool checkIssuer(shared_ptr issuer) const; + bool checkIssuer(const shared_ptr & issuer) const; - bool verify(shared_ptr caCert) const; + bool verify(const shared_ptr & caCert) const; bool verifyHostName (const string& hostname, @@ -81,7 +81,7 @@ public: const byteArray getEncoded() const; const string getType() const; int getVersion() const; - bool equals(shared_ptr other) const; + bool equals(const shared_ptr & other) const; void* getInternalData(); private: diff --git a/src/vmime/security/defaultAuthenticator.cpp b/src/vmime/security/defaultAuthenticator.cpp index 1c66b6c6..5503de5f 100644 --- a/src/vmime/security/defaultAuthenticator.cpp +++ b/src/vmime/security/defaultAuthenticator.cpp @@ -109,7 +109,7 @@ const string defaultAuthenticator::getServiceName() const } -void defaultAuthenticator::setService(shared_ptr serv) +void defaultAuthenticator::setService(const shared_ptr & serv) { m_service = serv; } diff --git a/src/vmime/security/defaultAuthenticator.hpp b/src/vmime/security/defaultAuthenticator.hpp index 645d026e..d5b4d787 100644 --- a/src/vmime/security/defaultAuthenticator.hpp +++ b/src/vmime/security/defaultAuthenticator.hpp @@ -55,7 +55,7 @@ public: const string getServiceName() const; const string getAccessToken() const; - void setService(shared_ptr serv); + void setService(const shared_ptr & serv); weak_ptr getService() const; private: diff --git a/src/vmime/security/sasl/SASLAuthenticator.hpp b/src/vmime/security/sasl/SASLAuthenticator.hpp index 9f1881f5..d4dc113c 100644 --- a/src/vmime/security/sasl/SASLAuthenticator.hpp +++ b/src/vmime/security/sasl/SASLAuthenticator.hpp @@ -66,13 +66,13 @@ public: */ virtual const std::vector > getAcceptableMechanisms (const std::vector >& available, - shared_ptr suggested) const = 0; + const shared_ptr & suggested) const = 0; /** Set the SASL session which is using this authenticator. * * @param sess SASL session */ - virtual void setSASLSession(shared_ptr sess) = 0; + virtual void setSASLSession(const shared_ptr & sess) = 0; /** Set the SASL mechanism which has been selected for the * SASL authentication process. This may be called several times @@ -81,7 +81,7 @@ public: * * @param mech SASL mechanism */ - virtual void setSASLMechanism(shared_ptr mech) = 0; + virtual void setSASLMechanism(const shared_ptr & mech) = 0; }; diff --git a/src/vmime/security/sasl/SASLContext.cpp b/src/vmime/security/sasl/SASLContext.cpp index fc474129..09ffed05 100644 --- a/src/vmime/security/sasl/SASLContext.cpp +++ b/src/vmime/security/sasl/SASLContext.cpp @@ -71,7 +71,7 @@ shared_ptr SASLContext::create() shared_ptr SASLContext::createSession (const string& serviceName, - shared_ptr auth, shared_ptr mech) + const shared_ptr & auth, const shared_ptr & mech) { return SASLSession::create (serviceName, dynamicCast (shared_from_this()), auth, mech); diff --git a/src/vmime/security/sasl/SASLContext.hpp b/src/vmime/security/sasl/SASLContext.hpp index 7e1fff4a..58d6a932 100644 --- a/src/vmime/security/sasl/SASLContext.hpp +++ b/src/vmime/security/sasl/SASLContext.hpp @@ -68,7 +68,7 @@ public: */ shared_ptr createSession (const string& serviceName, - shared_ptr auth, shared_ptr mech); + const shared_ptr & auth, const shared_ptr & mech); /** Create an instance of an SASL mechanism. * diff --git a/src/vmime/security/sasl/SASLMechanism.hpp b/src/vmime/security/sasl/SASLMechanism.hpp index 03749b50..8e842c4f 100644 --- a/src/vmime/security/sasl/SASLMechanism.hpp +++ b/src/vmime/security/sasl/SASLMechanism.hpp @@ -74,7 +74,7 @@ public: * 'responseLen' are undetermined) */ virtual bool step - (shared_ptr sess, + (const shared_ptr & sess, const byte_t* challenge, const size_t challengeLen, byte_t** response, size_t* responseLen) = 0; @@ -109,7 +109,7 @@ public: * the encoding of data (in this case, the values in 'output' and * 'outputLen' are undetermined) */ - virtual void encode(shared_ptr sess, + virtual void encode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) = 0; @@ -126,7 +126,7 @@ public: * the encoding of data (in this case, the values in 'output' and * 'outputLen' are undetermined) */ - virtual void decode(shared_ptr sess, + virtual void decode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) = 0; }; diff --git a/src/vmime/security/sasl/SASLMechanismFactory.cpp b/src/vmime/security/sasl/SASLMechanismFactory.cpp index 7ccdce8d..5ded627a 100644 --- a/src/vmime/security/sasl/SASLMechanismFactory.cpp +++ b/src/vmime/security/sasl/SASLMechanismFactory.cpp @@ -69,7 +69,7 @@ SASLMechanismFactory* SASLMechanismFactory::getInstance() shared_ptr SASLMechanismFactory::create - (shared_ptr ctx, const string& name_) + (const shared_ptr & ctx, const string& name_) { const string name(utility::stringUtils::toUpper(name_)); diff --git a/src/vmime/security/sasl/SASLMechanismFactory.hpp b/src/vmime/security/sasl/SASLMechanismFactory.hpp index 6d328f01..d83b37a1 100644 --- a/src/vmime/security/sasl/SASLMechanismFactory.hpp +++ b/src/vmime/security/sasl/SASLMechanismFactory.hpp @@ -62,7 +62,7 @@ private: public: virtual shared_ptr create - (shared_ptr ctx, const string& name) = 0; + (const shared_ptr & ctx, const string& name) = 0; }; template @@ -70,7 +70,7 @@ private: { public: - shared_ptr create(shared_ptr ctx, const string& name) + shared_ptr create(const shared_ptr & ctx, const string& name) { return vmime::make_shared (ctx, name); } @@ -103,7 +103,7 @@ public: * @throw exceptions::no_such_mechanism if no mechanism is * registered for the specified name */ - shared_ptr create(shared_ptr ctx, const string& name); + shared_ptr create(const shared_ptr & ctx, const string& name); /** Return a list of supported mechanisms. This includes mechanisms * registered using registerMechanism() as well as the ones that diff --git a/src/vmime/security/sasl/SASLSession.cpp b/src/vmime/security/sasl/SASLSession.cpp index c7e4b2f9..28446fe3 100644 --- a/src/vmime/security/sasl/SASLSession.cpp +++ b/src/vmime/security/sasl/SASLSession.cpp @@ -43,8 +43,8 @@ namespace security { namespace sasl { -SASLSession::SASLSession(const string& serviceName, shared_ptr ctx, - shared_ptr auth, shared_ptr mech) +SASLSession::SASLSession(const string& serviceName, const shared_ptr & ctx, + const shared_ptr & auth, const shared_ptr & mech) : m_serviceName(serviceName), m_context(ctx), m_auth(auth), m_mech(mech), m_gsaslContext(0), m_gsaslSession(0) { @@ -70,8 +70,8 @@ SASLSession::~SASLSession() // static shared_ptr SASLSession::create - (const string& serviceName, shared_ptr ctx, - shared_ptr auth, shared_ptr mech) + (const string& serviceName, const shared_ptr & ctx, + const shared_ptr & auth, const shared_ptr & mech) { return shared_ptr (new SASLSession(serviceName, ctx, auth, mech)); } @@ -116,7 +116,7 @@ bool SASLSession::evaluateChallenge } -shared_ptr SASLSession::getSecuredSocket(shared_ptr sok) +shared_ptr SASLSession::getSecuredSocket(const shared_ptr & sok) { return make_shared (dynamicCast (shared_from_this()), sok); } diff --git a/src/vmime/security/sasl/SASLSession.hpp b/src/vmime/security/sasl/SASLSession.hpp index a915a901..65387bd3 100644 --- a/src/vmime/security/sasl/SASLSession.hpp +++ b/src/vmime/security/sasl/SASLSession.hpp @@ -66,8 +66,8 @@ public: * @param mech SASL mechanism */ static shared_ptr create - (const string& serviceName, shared_ptr ctx, - shared_ptr auth, shared_ptr mech); + (const string& serviceName, const shared_ptr & ctx, + const shared_ptr & auth, const shared_ptr & mech); /** Initialize this SASL session. This must be called before * calling any other method on this object (except accessors). @@ -123,7 +123,7 @@ public: * @param sok socket to wrap * @return secured socket */ - shared_ptr getSecuredSocket(shared_ptr sok); + shared_ptr getSecuredSocket(const shared_ptr & sok); /** Return the name of the service which is using this * SASL session (eg. "imap"). This value should be returned @@ -136,8 +136,8 @@ public: private: SASLSession - (const string& serviceName, shared_ptr ctx, - shared_ptr auth, shared_ptr mech); + (const string& serviceName, const shared_ptr & ctx, + const shared_ptr & auth, const shared_ptr & mech); const string m_serviceName; diff --git a/src/vmime/security/sasl/SASLSocket.cpp b/src/vmime/security/sasl/SASLSocket.cpp index ef7ed6da..4312ab35 100644 --- a/src/vmime/security/sasl/SASLSocket.cpp +++ b/src/vmime/security/sasl/SASLSocket.cpp @@ -46,7 +46,7 @@ namespace sasl { -SASLSocket::SASLSocket(shared_ptr sess, shared_ptr wrapped) +SASLSocket::SASLSocket(const shared_ptr & sess, const shared_ptr & wrapped) : m_session(sess), m_wrapped(wrapped), m_pendingBuffer(0), m_pendingPos(0), m_pendingLen(0) { @@ -102,7 +102,7 @@ shared_ptr SASLSocket::getTimeoutHandler() } -void SASLSocket::setTracer(shared_ptr tracer) +void SASLSocket::setTracer(const shared_ptr & tracer) { m_wrapped->setTracer(tracer); } diff --git a/src/vmime/security/sasl/SASLSocket.hpp b/src/vmime/security/sasl/SASLSocket.hpp index a280d8a8..7a732394 100644 --- a/src/vmime/security/sasl/SASLSocket.hpp +++ b/src/vmime/security/sasl/SASLSocket.hpp @@ -50,7 +50,7 @@ class VMIME_EXPORT SASLSocket : public net::socket { public: - SASLSocket(shared_ptr sess, shared_ptr wrapped); + SASLSocket(const shared_ptr & sess, const shared_ptr & wrapped); ~SASLSocket(); void connect(const string& address, const port_t port); @@ -78,7 +78,7 @@ public: shared_ptr getTimeoutHandler(); - void setTracer(shared_ptr tracer); + void setTracer(const shared_ptr & tracer); shared_ptr getTracer(); private: diff --git a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp index 01371dea..fe36bbab 100644 --- a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp +++ b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp @@ -53,7 +53,7 @@ XOAuth2SASLAuthenticator::~XOAuth2SASLAuthenticator() const std::vector > XOAuth2SASLAuthenticator::getAcceptableMechanisms (const std::vector >& available, - shared_ptr suggested) const + const shared_ptr & suggested) const { if (m_mode == MODE_EXCLUSIVE) { @@ -74,6 +74,8 @@ const std::vector > } else { + shared_ptr newSuggested(suggested); + for (size_t i = available.size() ; i != 0 ; --i) { shared_ptr mech = available[i - 1]; @@ -81,11 +83,11 @@ const std::vector > if ("XOAUTH2" == mech->getName()) { // Suggest using XOAuth2 - suggested = mech; + newSuggested = mech; } } - return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested); + return defaultSASLAuthenticator::getAcceptableMechanisms(available, newSuggested); } } diff --git a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp index cbccf0f5..84fa8917 100644 --- a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp +++ b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp @@ -59,7 +59,7 @@ public: const std::vector > getAcceptableMechanisms (const std::vector >& available, - shared_ptr suggested) const; + const shared_ptr & suggested) const; private: diff --git a/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp b/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp index a1150667..c699fa83 100644 --- a/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp +++ b/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp @@ -42,7 +42,7 @@ namespace security { namespace sasl { -XOAuth2SASLMechanism::XOAuth2SASLMechanism(shared_ptr ctx, const string& /* name */) +XOAuth2SASLMechanism::XOAuth2SASLMechanism(const shared_ptr & ctx, const string& /* name */) : m_context(ctx), m_complete(false) { } @@ -60,7 +60,7 @@ const string XOAuth2SASLMechanism::getName() const bool XOAuth2SASLMechanism::step - (shared_ptr sess, + (const shared_ptr & sess, const byte_t* /* challenge */, const size_t /* challengeLen */, byte_t** response, size_t* responseLen) { @@ -107,7 +107,7 @@ bool XOAuth2SASLMechanism::hasInitialResponse() const void XOAuth2SASLMechanism::encode - (shared_ptr /* sess */, + (const shared_ptr & /* sess */, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) { @@ -121,7 +121,7 @@ void XOAuth2SASLMechanism::encode void XOAuth2SASLMechanism::decode - (shared_ptr /* sess */, + (const shared_ptr & /* sess */, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) { diff --git a/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp b/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp index 37dbdae5..5a49267e 100644 --- a/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp +++ b/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp @@ -48,13 +48,13 @@ class VMIME_EXPORT XOAuth2SASLMechanism : public SASLMechanism { public: - XOAuth2SASLMechanism(shared_ptr ctx, const string& name); + XOAuth2SASLMechanism(const shared_ptr & ctx, const string& name); ~XOAuth2SASLMechanism(); const string getName() const; - bool step(shared_ptr sess, + bool step(const shared_ptr & sess, const byte_t* challenge, const size_t challengeLen, byte_t** response, size_t* responseLen); @@ -62,11 +62,11 @@ public: bool hasInitialResponse() const; - void encode(shared_ptr sess, + void encode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen); - void decode(shared_ptr sess, + void decode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen); diff --git a/src/vmime/security/sasl/builtinSASLMechanism.cpp b/src/vmime/security/sasl/builtinSASLMechanism.cpp index 9e352334..cbbb98c3 100644 --- a/src/vmime/security/sasl/builtinSASLMechanism.cpp +++ b/src/vmime/security/sasl/builtinSASLMechanism.cpp @@ -45,7 +45,7 @@ namespace security { namespace sasl { -builtinSASLMechanism::builtinSASLMechanism(shared_ptr ctx, const string& name) +builtinSASLMechanism::builtinSASLMechanism(const shared_ptr & ctx, const string& name) : m_context(ctx), m_name(name), m_complete(false) { } @@ -63,7 +63,7 @@ const string builtinSASLMechanism::getName() const bool builtinSASLMechanism::step - (shared_ptr sess, const byte_t* challenge, const size_t challengeLen, + (const shared_ptr & sess, const byte_t* challenge, const size_t challengeLen, byte_t** response, size_t* responseLen) { char* output = 0; @@ -128,7 +128,7 @@ bool builtinSASLMechanism::hasInitialResponse() const void builtinSASLMechanism::encode - (shared_ptr sess, const byte_t* input, const size_t inputLen, + (const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) { char* coutput = 0; @@ -161,7 +161,7 @@ void builtinSASLMechanism::encode void builtinSASLMechanism::decode - (shared_ptr sess, const byte_t* input, const size_t inputLen, + (const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen) { char* coutput = 0; diff --git a/src/vmime/security/sasl/builtinSASLMechanism.hpp b/src/vmime/security/sasl/builtinSASLMechanism.hpp index 6cecd1b9..a82c74af 100644 --- a/src/vmime/security/sasl/builtinSASLMechanism.hpp +++ b/src/vmime/security/sasl/builtinSASLMechanism.hpp @@ -49,13 +49,13 @@ class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism { public: - builtinSASLMechanism(shared_ptr ctx, const string& name); + builtinSASLMechanism(const shared_ptr & ctx, const string& name); ~builtinSASLMechanism(); const string getName() const; - bool step(shared_ptr sess, + bool step(const shared_ptr & sess, const byte_t* challenge, const size_t challengeLen, byte_t** response, size_t* responseLen); @@ -63,11 +63,11 @@ public: bool hasInitialResponse() const; - void encode(shared_ptr sess, + void encode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen); - void decode(shared_ptr sess, + void decode(const shared_ptr & sess, const byte_t* input, const size_t inputLen, byte_t** output, size_t* outputLen); diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp index 124f5c3f..44d4e18c 100644 --- a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp @@ -54,7 +54,7 @@ defaultSASLAuthenticator::~defaultSASLAuthenticator() const std::vector > defaultSASLAuthenticator::getAcceptableMechanisms (const std::vector >& available, - shared_ptr suggested) const + const shared_ptr & suggested) const { if (suggested) { @@ -113,7 +113,7 @@ const string defaultSASLAuthenticator::getServiceName() const } -void defaultSASLAuthenticator::setService(shared_ptr serv) +void defaultSASLAuthenticator::setService(const shared_ptr & serv) { m_service = serv; m_default.setService(serv); @@ -126,7 +126,7 @@ weak_ptr defaultSASLAuthenticator::getService() const } -void defaultSASLAuthenticator::setSASLSession(shared_ptr sess) +void defaultSASLAuthenticator::setSASLSession(const shared_ptr & sess) { m_saslSession = sess; } @@ -138,7 +138,7 @@ shared_ptr defaultSASLAuthenticator::getSASLSession() const } -void defaultSASLAuthenticator::setSASLMechanism(shared_ptr mech) +void defaultSASLAuthenticator::setSASLMechanism(const shared_ptr & mech) { m_saslMech = mech; } diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.hpp b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp index 07baf975..f73849be 100644 --- a/src/vmime/security/sasl/defaultSASLAuthenticator.hpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp @@ -52,7 +52,7 @@ public: const std::vector > getAcceptableMechanisms (const std::vector >& available, - shared_ptr suggested) const; + const shared_ptr & suggested) const; const string getUsername() const; const string getPassword() const; @@ -61,13 +61,13 @@ public: const string getServiceName() const; const string getAccessToken() const; - void setService(shared_ptr serv); + void setService(const shared_ptr & serv); weak_ptr getService() const; - void setSASLSession(shared_ptr sess); + void setSASLSession(const shared_ptr & sess); shared_ptr getSASLSession() const; - void setSASLMechanism(shared_ptr mech); + void setSASLMechanism(const shared_ptr & mech); shared_ptr getSASLMechanism() const; private: diff --git a/src/vmime/streamContentHandler.cpp b/src/vmime/streamContentHandler.cpp index 8676cc34..230a802a 100644 --- a/src/vmime/streamContentHandler.cpp +++ b/src/vmime/streamContentHandler.cpp @@ -39,7 +39,7 @@ streamContentHandler::streamContentHandler() } -streamContentHandler::streamContentHandler(shared_ptr is, +streamContentHandler::streamContentHandler(const shared_ptr & is, const size_t length, const vmime::encoding& enc) { setData(is, length, enc); @@ -76,7 +76,7 @@ streamContentHandler& streamContentHandler::operator=(const streamContentHandler } -void streamContentHandler::setData(shared_ptr is, +void streamContentHandler::setData(const shared_ptr & is, const size_t length, const vmime::encoding& enc) { m_encoding = enc; diff --git a/src/vmime/streamContentHandler.hpp b/src/vmime/streamContentHandler.hpp index 9b72c073..db1e8052 100644 --- a/src/vmime/streamContentHandler.hpp +++ b/src/vmime/streamContentHandler.hpp @@ -58,7 +58,7 @@ public: * @return a reference to a new content handler */ streamContentHandler - (shared_ptr is, + (const shared_ptr & is, const size_t length, const vmime::encoding& enc = NO_ENCODING); @@ -79,7 +79,7 @@ public: * from the stream is already encoded with the specified encoding */ void setData - (shared_ptr is, + (const shared_ptr & is, const size_t length, const vmime::encoding& enc = NO_ENCODING); diff --git a/src/vmime/text.cpp b/src/vmime/text.cpp index 939f4f81..28fda3ad 100644 --- a/src/vmime/text.cpp +++ b/src/vmime/text.cpp @@ -155,19 +155,19 @@ const string text::getConvertedText(const charset& dest, const charsetConverterO } -void text::appendWord(shared_ptr w) +void text::appendWord(const shared_ptr & w) { m_words.push_back(w); } -void text::insertWordBefore(const size_t pos, shared_ptr w) +void text::insertWordBefore(const size_t pos, const shared_ptr & w) { m_words.insert(m_words.begin() + pos, w); } -void text::insertWordAfter(const size_t pos, shared_ptr w) +void text::insertWordAfter(const size_t pos, const shared_ptr & w) { m_words.insert(m_words.begin() + pos + 1, w); } diff --git a/src/vmime/text.hpp b/src/vmime/text.hpp index d8c4571a..b11454cb 100644 --- a/src/vmime/text.hpp +++ b/src/vmime/text.hpp @@ -64,7 +64,7 @@ public: * * @param w word to append */ - void appendWord(shared_ptr w); + void appendWord(const shared_ptr & w); /** Insert a new word before the specified position. * @@ -72,14 +72,14 @@ public: * the beginning of the list) * @param w word to insert */ - void insertWordBefore(const size_t pos, shared_ptr w); + void insertWordBefore(const size_t pos, const shared_ptr & w); /** Insert a new word after the specified position. * * @param pos position of the word before the new word * @param w word to insert */ - void insertWordAfter(const size_t pos, shared_ptr w); + void insertWordAfter(const size_t pos, const shared_ptr & w); /** Remove the word at the specified position. * diff --git a/src/vmime/textPart.hpp b/src/vmime/textPart.hpp index 6348f8d7..4be0535d 100644 --- a/src/vmime/textPart.hpp +++ b/src/vmime/textPart.hpp @@ -79,7 +79,7 @@ public: * * @param text text of the part */ - virtual void setText(shared_ptr text) = 0; + virtual void setText(const shared_ptr & text) = 0; /** Return the actual body parts this text part is composed of. * For example, HTML parts are composed of two parts: one "text/html" @@ -94,7 +94,7 @@ public: * @param message the message * @param parent body part into which generate this part */ - virtual void generateIn(shared_ptr message, shared_ptr parent) const = 0; + virtual void generateIn(const shared_ptr & message, const shared_ptr & parent) const = 0; /** Parse the text part(s) from the specified message. * @@ -102,7 +102,7 @@ public: * @param parent part containing the text part * @param textPart actual text part */ - virtual void parse(shared_ptr message, shared_ptr parent, shared_ptr textPart) = 0; + virtual void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart) = 0; }; diff --git a/src/vmime/utility/childProcess.hpp b/src/vmime/utility/childProcess.hpp index ebefcf0a..4898e3f7 100644 --- a/src/vmime/utility/childProcess.hpp +++ b/src/vmime/utility/childProcess.hpp @@ -59,7 +59,7 @@ public: * @throws exceptions::system_error if the an error occurs * before the process can be started */ - virtual void start(const std::vector args, const int flags = 0) = 0; + virtual void start(const std::vector & args, const int flags = 0) = 0; /** Return a wrapper to the child process standard input. * diff --git a/src/vmime/utility/parserInputStreamAdapter.cpp b/src/vmime/utility/parserInputStreamAdapter.cpp index f1eb0e70..ee6a58dd 100644 --- a/src/vmime/utility/parserInputStreamAdapter.cpp +++ b/src/vmime/utility/parserInputStreamAdapter.cpp @@ -28,7 +28,7 @@ namespace vmime { namespace utility { -parserInputStreamAdapter::parserInputStreamAdapter(shared_ptr stream) +parserInputStreamAdapter::parserInputStreamAdapter(const shared_ptr & stream) : m_stream(stream) { } diff --git a/src/vmime/utility/parserInputStreamAdapter.hpp b/src/vmime/utility/parserInputStreamAdapter.hpp index 9b0639b1..f6e360cb 100644 --- a/src/vmime/utility/parserInputStreamAdapter.hpp +++ b/src/vmime/utility/parserInputStreamAdapter.hpp @@ -43,7 +43,7 @@ public: /** @param stream input stream to wrap */ - parserInputStreamAdapter(shared_ptr stream); + parserInputStreamAdapter(const shared_ptr & stream); shared_ptr getUnderlyingStream(); diff --git a/src/vmime/utility/seekableInputStreamRegionAdapter.cpp b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp index cede1ba9..6306d3dc 100644 --- a/src/vmime/utility/seekableInputStreamRegionAdapter.cpp +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp @@ -29,7 +29,7 @@ namespace utility { seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter - (shared_ptr stream, const size_t begin, const size_t length) + (const shared_ptr & stream, const size_t begin, const size_t length) : m_stream(stream), m_begin(begin), m_length(length), m_position(0) { } diff --git a/src/vmime/utility/seekableInputStreamRegionAdapter.hpp b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp index 4716d2de..70ab8ff3 100644 --- a/src/vmime/utility/seekableInputStreamRegionAdapter.hpp +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp @@ -45,7 +45,7 @@ public: * @param begin start position in source stream * @param length region length in source stream */ - seekableInputStreamRegionAdapter(shared_ptr stream, + seekableInputStreamRegionAdapter(const shared_ptr & stream, const size_t begin, const size_t length); bool eof() const; diff --git a/src/vmime/utility/sync/autoLock.hpp b/src/vmime/utility/sync/autoLock.hpp index c058429d..a0ac90f6 100644 --- a/src/vmime/utility/sync/autoLock.hpp +++ b/src/vmime/utility/sync/autoLock.hpp @@ -41,7 +41,7 @@ class VMIME_EXPORT autoLock : public object { public: - autoLock(shared_ptr mutex) + autoLock(const shared_ptr & mutex) : m_mutex(mutex) { m_mutex->lock(); diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp index 4d4a2623..6bd3b7db 100644 --- a/tests/parser/attachmentHelperTest.cpp +++ b/tests/parser/attachmentHelperTest.cpp @@ -39,7 +39,7 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VMIME_TEST_LIST_END - static const vmime::string getStructure(vmime::shared_ptr part) + static const vmime::string getStructure(const vmime::shared_ptr & part) { vmime::shared_ptr bdy = part->getBody(); @@ -63,7 +63,7 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) return res + "]"; } - static const vmime::string extractBodyContents(vmime::shared_ptr part) + static const vmime::string extractBodyContents(const vmime::shared_ptr & part) { vmime::shared_ptr cth = part->getBody()->getContents(); diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp index 4dc5d670..e6ff737a 100644 --- a/tests/parser/bodyPartTest.cpp +++ b/tests/parser/bodyPartTest.cpp @@ -49,7 +49,7 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) buffer.begin() + c.getParsedOffset() + c.getParsedLength()); } - static const vmime::string extractContents(const vmime::shared_ptr cts) + static const vmime::string extractContents(const vmime::shared_ptr & cts) { std::ostringstream oss; vmime::utility::outputStreamAdapter os(oss); diff --git a/tests/parser/htmlTextPartTest.cpp b/tests/parser/htmlTextPartTest.cpp index 278a87c1..9eef5e84 100644 --- a/tests/parser/htmlTextPartTest.cpp +++ b/tests/parser/htmlTextPartTest.cpp @@ -35,7 +35,7 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) static const vmime::string extractContent - (vmime::shared_ptr cth) + (const vmime::shared_ptr & cth) { std::ostringstream oss; vmime::utility::outputStreamAdapter osa(oss); diff --git a/tests/testUtils.cpp b/tests/testUtils.cpp index 1e8e0c99..6e31d93f 100644 --- a/tests/testUtils.cpp +++ b/tests/testUtils.cpp @@ -90,7 +90,7 @@ vmime::shared_ptr testSocket::getTimeoutHandler() } -void testSocket::setTracer(vmime::shared_ptr /* tracer */) +void testSocket::setTracer(const vmime::shared_ptr & /* tracer */) { } diff --git a/tests/testUtils.hpp b/tests/testUtils.hpp index 367be623..d17c38b2 100644 --- a/tests/testUtils.hpp +++ b/tests/testUtils.hpp @@ -275,7 +275,7 @@ public: vmime::shared_ptr getTimeoutHandler(); - void setTracer(vmime::shared_ptr tracer); + void setTracer(const vmime::shared_ptr & tracer); vmime::shared_ptr getTracer(); /** Send data to client. @@ -336,7 +336,7 @@ public: return vmime::make_shared (); } - vmime::shared_ptr create(vmime::shared_ptr /* th */) + vmime::shared_ptr create(const vmime::shared_ptr & /* th */) { return vmime::make_shared (); } From d4c386beda2e6f418cacf79e29c2ddd84e5e6766 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Sat, 18 Aug 2018 19:51:21 +0200 Subject: [PATCH 21/27] Removed useless 'constCast's. --- src/vmime/net/imap/IMAPMessage.cpp | 4 ++-- .../net/imap/IMAPMessagePartContentHandler.cpp | 16 +++++++--------- src/vmime/net/maildir/maildirFormat.cpp | 12 +++--------- src/vmime/net/maildir/maildirFormat.hpp | 10 ++-------- src/vmime/net/pop3/POP3Message.cpp | 2 +- .../security/sasl/defaultSASLAuthenticator.cpp | 2 +- 6 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/vmime/net/imap/IMAPMessage.cpp b/src/vmime/net/imap/IMAPMessage.cpp index f0d2ebd3..87f78f38 100644 --- a/src/vmime/net/imap/IMAPMessage.cpp +++ b/src/vmime/net/imap/IMAPMessage.cpp @@ -414,11 +414,11 @@ size_t IMAPMessage::extractImpl IMAPCommand::FETCH( m_uid.empty() ? messageSet::byNumber(m_num) : messageSet::byUID(m_uid), fetchParams - )->send(constCast (folder)->m_connection); + )->send(folder->m_connection); // Get the response scoped_ptr resp - (constCast (folder)->m_connection->readResponse(&literalHandler)); + (folder->m_connection->readResponse(&literalHandler)); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp index 32a2a75b..0917d0f7 100644 --- a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp @@ -52,17 +52,15 @@ IMAPMessagePartContentHandler::IMAPMessagePartContentHandler shared_ptr IMAPMessagePartContentHandler::clone() const { return make_shared - (constCast (m_message.lock()), - constCast (m_part.lock()), - m_encoding); + (m_message.lock(), m_part.lock(), m_encoding); } void IMAPMessagePartContentHandler::generate (utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength) const { - shared_ptr msg = constCast (m_message.lock()); - shared_ptr part = constCast (m_part.lock()); + shared_ptr msg = m_message.lock(); + shared_ptr part = m_part.lock(); // Data is already encoded if (isEncoded()) @@ -128,8 +126,8 @@ void IMAPMessagePartContentHandler::generate void IMAPMessagePartContentHandler::extract (utility::outputStream& os, utility::progressListener* progress) const { - shared_ptr msg = constCast (m_message.lock()); - shared_ptr part = constCast (m_part.lock()); + shared_ptr msg = m_message.lock(); + shared_ptr part = m_part.lock(); // No decoding to perform if (!isEncoded()) @@ -158,8 +156,8 @@ void IMAPMessagePartContentHandler::extract void IMAPMessagePartContentHandler::extractRaw (utility::outputStream& os, utility::progressListener* progress) const { - shared_ptr msg = constCast (m_message.lock()); - shared_ptr part = constCast (m_part.lock()); + shared_ptr msg = m_message.lock(); + shared_ptr part = m_part.lock(); msg->extractPart(part, os, progress); } diff --git a/src/vmime/net/maildir/maildirFormat.cpp b/src/vmime/net/maildir/maildirFormat.cpp index 5b0b3c2b..7f2cb5f1 100644 --- a/src/vmime/net/maildir/maildirFormat.cpp +++ b/src/vmime/net/maildir/maildirFormat.cpp @@ -56,9 +56,9 @@ maildirFormat::context::context(const shared_ptr & store) } -shared_ptr maildirFormat::context::getStore() const +shared_ptr maildirFormat::context::getStore() { - return constCast (m_store.lock()); + return m_store.lock(); } @@ -72,13 +72,7 @@ maildirFormat::maildirFormat(const shared_ptr & ctx) } -shared_ptr maildirFormat::getContext() -{ - return m_context; -} - - -shared_ptr maildirFormat::getContext() const +shared_ptr maildirFormat::getContext() const { return m_context; } diff --git a/src/vmime/net/maildir/maildirFormat.hpp b/src/vmime/net/maildir/maildirFormat.hpp index 7a95caf4..733303bd 100644 --- a/src/vmime/net/maildir/maildirFormat.hpp +++ b/src/vmime/net/maildir/maildirFormat.hpp @@ -57,7 +57,7 @@ public: context(const shared_ptr & store); - shared_ptr getStore() const; + shared_ptr getStore(); private: @@ -162,13 +162,7 @@ protected: * * @return current context */ - shared_ptr getContext(); - - /** Returns the current context (const version). - * - * @return current context - */ - shared_ptr getContext() const; + shared_ptr getContext() const; /** Quick checks whether this implementation can read the Maildir * format in the specified directory. diff --git a/src/vmime/net/pop3/POP3Message.cpp b/src/vmime/net/pop3/POP3Message.cpp index 24d211a4..913219b3 100644 --- a/src/vmime/net/pop3/POP3Message.cpp +++ b/src/vmime/net/pop3/POP3Message.cpp @@ -149,7 +149,7 @@ void POP3Message::extract throw exceptions::partial_fetch_not_supported(); // Emit the "RETR" command - shared_ptr store = constCast (folder)->m_store.lock(); + shared_ptr store = folder->m_store.lock(); POP3Command::RETR(m_num)->send(store->getConnection()); diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp index 44d4e18c..2dbc0399 100644 --- a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp @@ -134,7 +134,7 @@ void defaultSASLAuthenticator::setSASLSession(const shared_ptr & se shared_ptr defaultSASLAuthenticator::getSASLSession() const { - return constCast (m_saslSession.lock()); + return m_saslSession.lock(); } From b55bdc9c0bb68236aa2de0a8eaec9f4c80cc2769 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Wed, 5 Sep 2018 23:54:48 +0200 Subject: [PATCH 22/27] Code style and clarity. --- HACKING | 94 +- doc/book/basics.tex | 95 +- doc/book/intro.tex | 4 +- doc/book/msg.tex | 131 +- doc/book/net.tex | 144 +- doc/book/start.tex | 4 +- examples/example1.cpp | 43 +- examples/example2.cpp | 53 +- examples/example3.cpp | 76 +- examples/example4.cpp | 49 +- examples/example5.cpp | 35 +- examples/example6.cpp | 407 +-- examples/example6_authenticator.hpp | 66 +- examples/example6_certificateVerifier.hpp | 38 +- examples/example6_timeoutHandler.hpp | 29 +- examples/example6_tracer.hpp | 42 +- examples/example7.cpp | 41 +- examples/viewer/viewer.cpp | 78 +- src/vmime/address.cpp | 206 +- src/vmime/address.hpp | 20 +- src/vmime/addressList.cpp | 227 +- src/vmime/addressList.hpp | 42 +- src/vmime/attachment.hpp | 8 +- src/vmime/attachmentHelper.cpp | 223 +- src/vmime/attachmentHelper.hpp | 50 +- src/vmime/base.cpp | 17 +- src/vmime/base.hpp | 80 +- src/vmime/body.cpp | 726 +++-- src/vmime/body.hpp | 73 +- src/vmime/bodyPart.cpp | 116 +- src/vmime/bodyPart.hpp | 32 +- src/vmime/bodyPartAttachment.cpp | 93 +- src/vmime/bodyPartAttachment.hpp | 10 +- src/vmime/charset.cpp | 171 +- src/vmime/charset.hpp | 52 +- src/vmime/charsetConverter.cpp | 23 +- src/vmime/charsetConverter.hpp | 48 +- src/vmime/charsetConverterOptions.cpp | 9 +- src/vmime/charsetConverterOptions.hpp | 8 +- src/vmime/charsetConverter_iconv.cpp | 268 +- src/vmime/charsetConverter_iconv.hpp | 34 +- src/vmime/charsetConverter_icu.cpp | 376 ++- src/vmime/charsetConverter_icu.hpp | 35 +- src/vmime/charsetConverter_idna.cpp | 121 +- src/vmime/charsetConverter_idna.hpp | 22 +- src/vmime/charsetConverter_win.cpp | 155 +- src/vmime/charsetConverter_win.hpp | 21 +- src/vmime/component.cpp | 183 +- src/vmime/component.hpp | 120 +- src/vmime/constants.cpp | 41 +- src/vmime/constants.hpp | 42 +- src/vmime/contentDisposition.cpp | 97 +- src/vmime/contentDisposition.hpp | 32 +- src/vmime/contentDispositionField.cpp | 98 +- src/vmime/contentDispositionField.hpp | 8 +- src/vmime/contentHandler.cpp | 9 +- src/vmime/contentHandler.hpp | 25 +- src/vmime/contentTypeField.cpp | 65 +- src/vmime/contentTypeField.hpp | 9 +- src/vmime/context.cpp | 41 +- src/vmime/context.hpp | 20 +- src/vmime/dateTime.cpp | 717 +++-- src/vmime/dateTime.hpp | 60 +- src/vmime/defaultAttachment.cpp | 98 +- src/vmime/defaultAttachment.hpp | 25 +- src/vmime/disposition.cpp | 228 +- src/vmime/disposition.hpp | 40 +- src/vmime/emailAddress.cpp | 755 ++--- src/vmime/emailAddress.hpp | 32 +- src/vmime/emptyContentHandler.cpp | 97 +- src/vmime/emptyContentHandler.hpp | 26 +- src/vmime/encoding.cpp | 237 +- src/vmime/encoding.hpp | 52 +- src/vmime/exception.cpp | 41 +- src/vmime/exception.hpp | 188 +- src/vmime/export.hpp | 2 +- src/vmime/fileAttachment.cpp | 134 +- src/vmime/fileAttachment.hpp | 55 +- src/vmime/fileContentHandler.cpp | 46 +- src/vmime/fileContentHandler.hpp | 22 +- src/vmime/generatedMessageAttachment.cpp | 53 +- src/vmime/generatedMessageAttachment.hpp | 10 +- src/vmime/generationContext.cpp | 68 +- src/vmime/generationContext.hpp | 12 +- src/vmime/header.cpp | 271 +- src/vmime/header.hpp | 82 +- src/vmime/headerField.cpp | 247 +- src/vmime/headerField.hpp | 53 +- src/vmime/headerFieldFactory.cpp | 59 +- src/vmime/headerFieldFactory.hpp | 51 +- src/vmime/headerFieldValue.cpp | 9 +- src/vmime/headerFieldValue.hpp | 9 +- src/vmime/htmlTextPart.cpp | 364 ++- src/vmime/htmlTextPart.hpp | 71 +- src/vmime/mailbox.cpp | 439 +-- src/vmime/mailbox.hpp | 32 +- src/vmime/mailboxField.cpp | 50 +- src/vmime/mailboxField.hpp | 19 +- src/vmime/mailboxGroup.cpp | 301 +- src/vmime/mailboxGroup.hpp | 52 +- src/vmime/mailboxList.cpp | 174 +- src/vmime/mailboxList.hpp | 32 +- src/vmime/mdn/MDNHelper.cpp | 169 +- src/vmime/mdn/MDNHelper.hpp | 45 +- src/vmime/mdn/MDNInfos.cpp | 6 +- src/vmime/mdn/MDNInfos.hpp | 5 +- src/vmime/mdn/receivedMDNInfos.cpp | 66 +- src/vmime/mdn/receivedMDNInfos.hpp | 5 +- src/vmime/mdn/sendableMDNInfos.cpp | 33 +- src/vmime/mdn/sendableMDNInfos.hpp | 5 +- src/vmime/mediaType.cpp | 144 +- src/vmime/mediaType.hpp | 32 +- src/vmime/message.cpp | 17 +- src/vmime/message.hpp | 16 +- src/vmime/messageAttachment.hpp | 9 +- src/vmime/messageBuilder.cpp | 222 +- src/vmime/messageBuilder.hpp | 8 +- src/vmime/messageId.cpp | 229 +- src/vmime/messageId.hpp | 45 +- src/vmime/messageIdSequence.cpp | 189 +- src/vmime/messageIdSequence.hpp | 37 +- src/vmime/messageParser.cpp | 214 +- src/vmime/messageParser.hpp | 19 +- src/vmime/misc/importanceHelper.cpp | 121 +- src/vmime/misc/importanceHelper.hpp | 8 +- src/vmime/net/builtinServices.inl | 2 +- src/vmime/net/connectionInfos.hpp | 6 +- src/vmime/net/defaultConnectionInfos.cpp | 14 +- src/vmime/net/defaultConnectionInfos.hpp | 6 +- src/vmime/net/defaultTimeoutHandler.cpp | 26 +- src/vmime/net/defaultTimeoutHandler.hpp | 8 +- src/vmime/net/events.cpp | 88 +- src/vmime/net/events.hpp | 51 +- src/vmime/net/fetchAttributes.cpp | 39 +- src/vmime/net/fetchAttributes.hpp | 12 +- src/vmime/net/folder.cpp | 73 +- src/vmime/net/folder.hpp | 58 +- src/vmime/net/folderAttributes.cpp | 50 +- src/vmime/net/folderAttributes.hpp | 17 +- src/vmime/net/folderStatus.hpp | 5 +- src/vmime/net/imap/IMAPCommand.cpp | 231 +- src/vmime/net/imap/IMAPCommand.hpp | 6 +- src/vmime/net/imap/IMAPConnection.cpp | 557 ++-- src/vmime/net/imap/IMAPConnection.hpp | 9 +- src/vmime/net/imap/IMAPFolder.cpp | 1075 ++++--- src/vmime/net/imap/IMAPFolder.hpp | 55 +- src/vmime/net/imap/IMAPFolderStatus.cpp | 294 +- src/vmime/net/imap/IMAPFolderStatus.hpp | 5 +- src/vmime/net/imap/IMAPMessage.cpp | 671 ++-- src/vmime/net/imap/IMAPMessage.hpp | 51 +- src/vmime/net/imap/IMAPMessagePart.cpp | 156 +- src/vmime/net/imap/IMAPMessagePart.hpp | 26 +- .../imap/IMAPMessagePartContentHandler.cpp | 107 +- .../imap/IMAPMessagePartContentHandler.hpp | 18 +- src/vmime/net/imap/IMAPMessageStructure.cpp | 36 +- src/vmime/net/imap/IMAPMessageStructure.hpp | 6 +- src/vmime/net/imap/IMAPParser.hpp | 2818 +++++++++-------- src/vmime/net/imap/IMAPSStore.cpp | 27 +- src/vmime/net/imap/IMAPSStore.hpp | 5 +- src/vmime/net/imap/IMAPServiceInfos.cpp | 32 +- src/vmime/net/imap/IMAPServiceInfos.hpp | 8 +- src/vmime/net/imap/IMAPStore.cpp | 211 +- src/vmime/net/imap/IMAPStore.hpp | 12 +- src/vmime/net/imap/IMAPTag.cpp | 46 +- src/vmime/net/imap/IMAPTag.hpp | 6 +- src/vmime/net/imap/IMAPUtils.cpp | 618 ++-- src/vmime/net/imap/IMAPUtils.hpp | 2 +- src/vmime/net/imap/imap.hpp | 2 +- .../maildir/format/courierMaildirFormat.cpp | 469 +-- .../maildir/format/courierMaildirFormat.hpp | 24 +- .../net/maildir/format/kmailMaildirFormat.cpp | 237 +- .../net/maildir/format/kmailMaildirFormat.hpp | 24 +- src/vmime/net/maildir/maildir.hpp | 2 +- src/vmime/net/maildir/maildirFolder.cpp | 986 +++--- src/vmime/net/maildir/maildirFolder.hpp | 47 +- src/vmime/net/maildir/maildirFolderStatus.cpp | 30 +- src/vmime/net/maildir/maildirFolderStatus.hpp | 5 +- src/vmime/net/maildir/maildirFormat.cpp | 25 +- src/vmime/net/maildir/maildirFormat.hpp | 27 +- src/vmime/net/maildir/maildirMessage.cpp | 242 +- src/vmime/net/maildir/maildirMessage.hpp | 33 +- src/vmime/net/maildir/maildirMessagePart.cpp | 100 +- src/vmime/net/maildir/maildirMessagePart.hpp | 9 +- .../net/maildir/maildirMessageStructure.cpp | 36 +- .../net/maildir/maildirMessageStructure.hpp | 16 +- src/vmime/net/maildir/maildirServiceInfos.cpp | 21 +- src/vmime/net/maildir/maildirServiceInfos.hpp | 8 +- src/vmime/net/maildir/maildirStore.cpp | 198 +- src/vmime/net/maildir/maildirStore.hpp | 11 +- src/vmime/net/maildir/maildirUtils.cpp | 168 +- src/vmime/net/maildir/maildirUtils.hpp | 24 +- src/vmime/net/message.cpp | 62 +- src/vmime/net/message.hpp | 74 +- src/vmime/net/messageSet.cpp | 253 +- src/vmime/net/messageSet.hpp | 17 +- src/vmime/net/pop3/POP3Command.cpp | 107 +- src/vmime/net/pop3/POP3Command.hpp | 6 +- src/vmime/net/pop3/POP3Connection.cpp | 500 +-- src/vmime/net/pop3/POP3Connection.hpp | 12 +- src/vmime/net/pop3/POP3Folder.cpp | 533 ++-- src/vmime/net/pop3/POP3Folder.hpp | 40 +- src/vmime/net/pop3/POP3FolderStatus.cpp | 30 +- src/vmime/net/pop3/POP3FolderStatus.hpp | 5 +- src/vmime/net/pop3/POP3Message.cpp | 186 +- src/vmime/net/pop3/POP3Message.hpp | 31 +- src/vmime/net/pop3/POP3Response.cpp | 306 +- src/vmime/net/pop3/POP3Response.hpp | 34 +- src/vmime/net/pop3/POP3SStore.cpp | 27 +- src/vmime/net/pop3/POP3SStore.hpp | 11 +- src/vmime/net/pop3/POP3ServiceInfos.cpp | 33 +- src/vmime/net/pop3/POP3ServiceInfos.hpp | 8 +- src/vmime/net/pop3/POP3Store.cpp | 178 +- src/vmime/net/pop3/POP3Store.hpp | 12 +- src/vmime/net/pop3/POP3Utils.cpp | 56 +- src/vmime/net/pop3/POP3Utils.hpp | 17 +- src/vmime/net/pop3/pop3.hpp | 2 +- src/vmime/net/securedConnectionInfos.hpp | 6 +- src/vmime/net/sendmail/sendmail.hpp | 2 +- .../net/sendmail/sendmailServiceInfos.cpp | 21 +- .../net/sendmail/sendmailServiceInfos.hpp | 8 +- src/vmime/net/sendmail/sendmailTransport.cpp | 125 +- src/vmime/net/sendmail/sendmailTransport.hpp | 34 +- src/vmime/net/service.cpp | 88 +- src/vmime/net/service.hpp | 17 +- src/vmime/net/serviceFactory.cpp | 83 +- src/vmime/net/serviceFactory.hpp | 35 +- src/vmime/net/serviceInfos.cpp | 141 +- src/vmime/net/serviceInfos.hpp | 50 +- src/vmime/net/serviceRegistration.inl | 57 +- src/vmime/net/session.cpp | 96 +- src/vmime/net/session.hpp | 42 +- .../smtp/SMTPChunkingOutputStreamAdapter.cpp | 94 +- .../smtp/SMTPChunkingOutputStreamAdapter.hpp | 13 +- src/vmime/net/smtp/SMTPCommand.cpp | 110 +- src/vmime/net/smtp/SMTPCommand.hpp | 6 +- src/vmime/net/smtp/SMTPCommandSet.cpp | 75 +- src/vmime/net/smtp/SMTPCommandSet.hpp | 6 +- src/vmime/net/smtp/SMTPConnection.cpp | 499 +-- src/vmime/net/smtp/SMTPConnection.hpp | 14 +- src/vmime/net/smtp/SMTPExceptions.cpp | 88 +- src/vmime/net/smtp/SMTPExceptions.hpp | 28 +- src/vmime/net/smtp/SMTPResponse.cpp | 197 +- src/vmime/net/smtp/SMTPResponse.hpp | 35 +- src/vmime/net/smtp/SMTPSTransport.cpp | 27 +- src/vmime/net/smtp/SMTPSTransport.hpp | 11 +- src/vmime/net/smtp/SMTPServiceInfos.cpp | 32 +- src/vmime/net/smtp/SMTPServiceInfos.hpp | 8 +- src/vmime/net/smtp/SMTPTransport.cpp | 329 +- src/vmime/net/smtp/SMTPTransport.hpp | 53 +- src/vmime/net/smtp/smtp.hpp | 2 +- src/vmime/net/socket.hpp | 11 +- src/vmime/net/store.hpp | 23 +- src/vmime/net/timeoutHandler.hpp | 8 +- src/vmime/net/tls/TLSProperties.cpp | 2 +- src/vmime/net/tls/TLSProperties.hpp | 10 +- .../net/tls/TLSSecuredConnectionInfos.cpp | 31 +- .../net/tls/TLSSecuredConnectionInfos.hpp | 14 +- src/vmime/net/tls/TLSSession.cpp | 6 +- src/vmime/net/tls/TLSSession.hpp | 11 +- src/vmime/net/tls/TLSSocket.cpp | 2 +- src/vmime/net/tls/TLSSocket.hpp | 6 +- .../net/tls/gnutls/TLSProperties_GnuTLS.cpp | 56 +- .../net/tls/gnutls/TLSProperties_GnuTLS.hpp | 6 +- .../net/tls/gnutls/TLSSession_GnuTLS.cpp | 116 +- .../net/tls/gnutls/TLSSession_GnuTLS.hpp | 12 +- src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp | 395 +-- src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp | 6 +- .../net/tls/openssl/OpenSSLInitializer.cpp | 42 +- .../net/tls/openssl/OpenSSLInitializer.hpp | 17 +- .../net/tls/openssl/TLSProperties_OpenSSL.cpp | 56 +- .../net/tls/openssl/TLSProperties_OpenSSL.hpp | 6 +- .../net/tls/openssl/TLSSession_OpenSSL.cpp | 56 +- .../net/tls/openssl/TLSSession_OpenSSL.hpp | 19 +- .../net/tls/openssl/TLSSocket_OpenSSL.cpp | 530 ++-- .../net/tls/openssl/TLSSocket_OpenSSL.hpp | 12 +- src/vmime/net/tracer.cpp | 16 +- src/vmime/net/tracer.hpp | 17 +- src/vmime/net/transport.cpp | 152 +- src/vmime/net/transport.hpp | 44 +- src/vmime/object.cpp | 21 +- src/vmime/object.hpp | 9 +- src/vmime/parameter.cpp | 443 +-- src/vmime/parameter.hpp | 45 +- src/vmime/parameterizedHeaderField.cpp | 381 ++- src/vmime/parameterizedHeaderField.hpp | 52 +- src/vmime/parsedMessageAttachment.cpp | 50 +- src/vmime/parsedMessageAttachment.hpp | 10 +- src/vmime/parserHelpers.hpp | 83 +- src/vmime/parsingContext.cpp | 30 +- src/vmime/parsingContext.hpp | 34 +- src/vmime/path.cpp | 148 +- src/vmime/path.hpp | 32 +- src/vmime/plainTextPart.cpp | 75 +- src/vmime/plainTextPart.hpp | 20 +- src/vmime/platform.cpp | 22 +- src/vmime/platform.hpp | 15 +- .../platforms/posix/posixChildProcess.cpp | 236 +- .../platforms/posix/posixChildProcess.hpp | 10 +- .../platforms/posix/posixCriticalSection.cpp | 18 +- .../platforms/posix/posixCriticalSection.hpp | 6 +- src/vmime/platforms/posix/posixFile.cpp | 513 +-- src/vmime/platforms/posix/posixFile.hpp | 36 +- src/vmime/platforms/posix/posixHandler.cpp | 130 +- src/vmime/platforms/posix/posixHandler.hpp | 6 +- src/vmime/platforms/posix/posixSocket.cpp | 620 ++-- src/vmime/platforms/posix/posixSocket.hpp | 10 +- .../platforms/windows/windowsCodepages.hpp | 10 +- .../windows/windowsCriticalSection.cpp | 18 +- .../windows/windowsCriticalSection.hpp | 6 +- src/vmime/platforms/windows/windowsFile.cpp | 573 ++-- src/vmime/platforms/windows/windowsFile.hpp | 36 +- .../platforms/windows/windowsHandler.cpp | 184 +- .../platforms/windows/windowsHandler.hpp | 6 +- src/vmime/platforms/windows/windowsSocket.cpp | 320 +- src/vmime/platforms/windows/windowsSocket.hpp | 10 +- src/vmime/propertySet.cpp | 273 +- src/vmime/propertySet.hpp | 161 +- src/vmime/relay.cpp | 241 +- src/vmime/relay.hpp | 32 +- src/vmime/security/authenticator.hpp | 7 +- src/vmime/security/cert/X509Certificate.cpp | 20 +- src/vmime/security/cert/X509Certificate.hpp | 36 +- src/vmime/security/cert/certificate.hpp | 6 +- src/vmime/security/cert/certificateChain.cpp | 14 +- src/vmime/security/cert/certificateChain.hpp | 6 +- .../security/cert/certificateException.cpp | 30 +- .../security/cert/certificateException.hpp | 6 +- .../cert/certificateExpiredException.cpp | 6 +- .../cert/certificateExpiredException.hpp | 6 +- ...certificateIssuerVerificationException.cpp | 10 +- ...certificateIssuerVerificationException.hpp | 6 +- .../cert/certificateNotTrustedException.cpp | 10 +- .../cert/certificateNotTrustedException.hpp | 6 +- .../cert/certificateNotYetValidException.cpp | 10 +- .../cert/certificateNotYetValidException.hpp | 6 +- .../security/cert/certificateVerifier.hpp | 6 +- .../cert/defaultCertificateVerifier.cpp | 90 +- .../cert/defaultCertificateVerifier.hpp | 6 +- .../cert/gnutls/X509Certificate_GnuTLS.cpp | 214 +- .../cert/gnutls/X509Certificate_GnuTLS.hpp | 13 +- .../cert/openssl/X509Certificate_OpenSSL.cpp | 305 +- .../cert/openssl/X509Certificate_OpenSSL.hpp | 13 +- .../security/cert/serverIdentityException.cpp | 10 +- .../security/cert/serverIdentityException.hpp | 6 +- .../unsupportedCertificateTypeException.cpp | 14 +- .../unsupportedCertificateTypeException.hpp | 6 +- src/vmime/security/defaultAuthenticator.cpp | 52 +- src/vmime/security/defaultAuthenticator.hpp | 7 +- .../security/digest/md5/md5MessageDigest.cpp | 102 +- .../security/digest/md5/md5MessageDigest.hpp | 9 +- src/vmime/security/digest/messageDigest.cpp | 9 +- src/vmime/security/digest/messageDigest.hpp | 28 +- .../security/digest/messageDigestFactory.cpp | 35 +- .../security/digest/messageDigestFactory.hpp | 30 +- .../digest/sha1/sha1MessageDigest.cpp | 110 +- .../digest/sha1/sha1MessageDigest.hpp | 6 +- src/vmime/security/sasl/SASLAuthenticator.hpp | 14 +- src/vmime/security/sasl/SASLContext.cpp | 150 +- src/vmime/security/sasl/SASLContext.hpp | 20 +- src/vmime/security/sasl/SASLMechanism.hpp | 38 +- .../security/sasl/SASLMechanismFactory.cpp | 60 +- .../security/sasl/SASLMechanismFactory.hpp | 39 +- src/vmime/security/sasl/SASLSession.cpp | 158 +- src/vmime/security/sasl/SASLSession.hpp | 34 +- src/vmime/security/sasl/SASLSocket.cpp | 153 +- src/vmime/security/sasl/SASLSocket.hpp | 13 +- .../sasl/XOAuth2SASLAuthenticator.cpp | 43 +- .../sasl/XOAuth2SASLAuthenticator.hpp | 17 +- .../security/sasl/XOAuth2SASLMechanism.cpp | 67 +- .../security/sasl/XOAuth2SASLMechanism.hpp | 37 +- .../security/sasl/builtinSASLMechanism.cpp | 147 +- .../security/sasl/builtinSASLMechanism.hpp | 36 +- .../sasl/defaultSASLAuthenticator.cpp | 86 +- .../sasl/defaultSASLAuthenticator.hpp | 14 +- src/vmime/streamContentHandler.cpp | 165 +- src/vmime/streamContentHandler.hpp | 32 +- src/vmime/stringContentHandler.cpp | 183 +- src/vmime/stringContentHandler.hpp | 50 +- src/vmime/text.cpp | 363 ++- src/vmime/text.hpp | 57 +- src/vmime/textPart.hpp | 19 +- src/vmime/textPartFactory.cpp | 27 +- src/vmime/textPartFactory.hpp | 20 +- src/vmime/types.hpp | 13 +- src/vmime/utility/childProcess.hpp | 12 +- src/vmime/utility/datetimeUtils.cpp | 204 +- src/vmime/utility/datetimeUtils.hpp | 5 +- src/vmime/utility/encoder/b64Encoder.cpp | 181 +- src/vmime/utility/encoder/b64Encoder.hpp | 18 +- src/vmime/utility/encoder/binaryEncoder.cpp | 6 +- src/vmime/utility/encoder/binaryEncoder.hpp | 5 +- src/vmime/utility/encoder/eightBitEncoder.cpp | 6 +- src/vmime/utility/encoder/eightBitEncoder.hpp | 5 +- src/vmime/utility/encoder/encoder.cpp | 40 +- src/vmime/utility/encoder/encoder.hpp | 17 +- src/vmime/utility/encoder/encoderFactory.cpp | 75 +- src/vmime/utility/encoder/encoderFactory.hpp | 29 +- src/vmime/utility/encoder/noopEncoder.cpp | 37 +- src/vmime/utility/encoder/noopEncoder.hpp | 18 +- src/vmime/utility/encoder/qpEncoder.cpp | 492 +-- src/vmime/utility/encoder/qpEncoder.hpp | 18 +- src/vmime/utility/encoder/sevenBitEncoder.cpp | 6 +- src/vmime/utility/encoder/sevenBitEncoder.hpp | 3 +- src/vmime/utility/encoder/uuEncoder.cpp | 290 +- src/vmime/utility/encoder/uuEncoder.hpp | 18 +- src/vmime/utility/file.hpp | 17 +- src/vmime/utility/filteredStream.cpp | 253 +- src/vmime/utility/filteredStream.hpp | 176 +- src/vmime/utility/inputStream.cpp | 2 +- src/vmime/utility/inputStream.hpp | 5 +- src/vmime/utility/inputStreamAdapter.cpp | 39 +- src/vmime/utility/inputStreamAdapter.hpp | 5 +- .../utility/inputStreamByteBufferAdapter.cpp | 57 +- .../utility/inputStreamByteBufferAdapter.hpp | 6 +- .../utility/inputStreamPointerAdapter.cpp | 18 +- .../utility/inputStreamPointerAdapter.hpp | 6 +- .../utility/inputStreamSocketAdapter.cpp | 29 +- .../utility/inputStreamSocketAdapter.hpp | 6 +- .../utility/inputStreamStringAdapter.cpp | 86 +- .../utility/inputStreamStringAdapter.hpp | 6 +- .../utility/inputStreamStringProxyAdapter.cpp | 68 +- .../utility/inputStreamStringProxyAdapter.hpp | 6 +- src/vmime/utility/outputStream.cpp | 11 +- src/vmime/utility/outputStream.hpp | 29 +- src/vmime/utility/outputStreamAdapter.cpp | 16 +- src/vmime/utility/outputStreamAdapter.hpp | 6 +- .../utility/outputStreamByteArrayAdapter.cpp | 16 +- .../utility/outputStreamByteArrayAdapter.hpp | 6 +- .../utility/outputStreamSocketAdapter.cpp | 21 +- .../utility/outputStreamSocketAdapter.hpp | 6 +- .../utility/outputStreamStringAdapter.cpp | 16 +- .../utility/outputStreamStringAdapter.hpp | 6 +- .../utility/parserInputStreamAdapter.cpp | 85 +- .../utility/parserInputStreamAdapter.hpp | 62 +- src/vmime/utility/path.cpp | 214 +- src/vmime/utility/path.hpp | 5 +- src/vmime/utility/progressListener.cpp | 43 +- src/vmime/utility/progressListener.hpp | 9 +- src/vmime/utility/random.cpp | 38 +- src/vmime/utility/random.hpp | 11 +- src/vmime/utility/seekableInputStream.hpp | 6 +- .../seekableInputStreamRegionAdapter.cpp | 67 +- .../seekableInputStreamRegionAdapter.hpp | 13 +- src/vmime/utility/stream.cpp | 7 +- src/vmime/utility/stream.hpp | 6 +- src/vmime/utility/streamUtils.cpp | 65 +- src/vmime/utility/streamUtils.hpp | 22 +- src/vmime/utility/stringProxy.cpp | 98 +- src/vmime/utility/stringProxy.hpp | 12 +- src/vmime/utility/stringUtils.cpp | 214 +- src/vmime/utility/stringUtils.hpp | 62 +- src/vmime/utility/sync/autoLock.hpp | 15 +- src/vmime/utility/sync/criticalSection.cpp | 10 +- src/vmime/utility/sync/criticalSection.hpp | 5 +- src/vmime/utility/url.cpp | 264 +- src/vmime/utility/url.hpp | 20 +- src/vmime/utility/urlUtils.cpp | 110 +- src/vmime/utility/urlUtils.hpp | 5 +- src/vmime/vmime.hpp | 2 +- src/vmime/word.cpp | 578 ++-- src/vmime/word.hpp | 115 +- src/vmime/wordEncoder.cpp | 186 +- src/vmime/wordEncoder.hpp | 28 +- tests/misc/importanceHelperTest.cpp | 129 +- tests/net/folderAttributesTest.cpp | 34 +- tests/net/imap/IMAPCommandTest.cpp | 152 +- tests/net/imap/IMAPParserTest.cpp | 30 +- tests/net/imap/IMAPTagTest.cpp | 24 +- tests/net/imap/IMAPUtilsTest.cpp | 38 +- tests/net/maildir/maildirStoreTest.cpp | 223 +- tests/net/maildir/maildirUtilsTest.cpp | 13 +- tests/net/messageSetTest.cpp | 106 +- tests/net/pop3/POP3CommandTest.cpp | 95 +- tests/net/pop3/POP3ResponseTest.cpp | 80 +- tests/net/pop3/POP3StoreTest.cpp | 10 +- tests/net/pop3/POP3TestUtils.hpp | 33 +- tests/net/pop3/POP3UtilsTest.cpp | 23 +- tests/net/smtp/SMTPCommandSetTest.cpp | 34 +- tests/net/smtp/SMTPCommandTest.cpp | 119 +- tests/net/smtp/SMTPResponseTest.cpp | 84 +- tests/net/smtp/SMTPTransportTest.cpp | 112 +- tests/net/smtp/SMTPTransportTestUtils.hpp | 509 +-- tests/parser/attachmentHelperTest.cpp | 91 +- tests/parser/bodyPartTest.cpp | 81 +- tests/parser/bodyTest.cpp | 46 +- .../charsetFilteredOutputStreamTest.cpp | 38 +- tests/parser/charsetTest.cpp | 92 +- tests/parser/charsetTestSuites.hpp | 11 +- tests/parser/datetimeTest.cpp | 26 +- tests/parser/dispositionTest.cpp | 15 +- tests/parser/emailAddressTest.cpp | 127 +- tests/parser/emptyContentHandlerTest.cpp | 26 +- tests/parser/fileContentHandlerTest.cpp | 41 +- tests/parser/headerFieldTest.cpp | 38 +- tests/parser/headerTest.cpp | 97 +- tests/parser/htmlTextPartTest.cpp | 34 +- tests/parser/mailboxGroupTest.cpp | 18 +- tests/parser/mailboxListTest.cpp | 7 +- tests/parser/mailboxTest.cpp | 27 +- tests/parser/mediaTypeTest.cpp | 23 +- tests/parser/messageIdSequenceTest.cpp | 11 +- tests/parser/messageIdTest.cpp | 15 +- tests/parser/messageTest.cpp | 19 +- tests/parser/parameterTest.cpp | 335 +- tests/parser/pathTest.cpp | 15 +- tests/parser/streamContentHandlerTest.cpp | 59 +- tests/parser/stringContentHandlerTest.cpp | 82 +- tests/parser/textTest.cpp | 423 ++- tests/parser/wordEncoderTest.cpp | 127 +- tests/security/digest/md5Test.cpp | 63 +- tests/security/digest/sha1Test.cpp | 26 +- tests/testRunner.cpp | 139 +- tests/testUtils.cpp | 201 +- tests/testUtils.hpp | 147 +- tests/utility/datetimeUtilsTest.cpp | 43 +- tests/utility/encoder/b64EncoderTest.cpp | 55 +- tests/utility/encoder/encoderFactoryTest.cpp | 10 +- tests/utility/encoder/encoderTestUtils.hpp | 31 +- tests/utility/encoder/qpEncoderTest.cpp | 115 +- tests/utility/filteredStreamTest.cpp | 105 +- .../outputStreamByteArrayAdapterTest.cpp | 15 +- .../utility/outputStreamSocketAdapterTest.cpp | 15 +- .../utility/outputStreamStringAdapterTest.cpp | 15 +- .../utility/parserInputStreamAdapterTest.cpp | 6 +- tests/utility/pathTest.cpp | 79 +- .../seekableInputStreamRegionAdapterTest.cpp | 57 +- tests/utility/stringProxyTest.cpp | 31 +- tests/utility/stringUtilsTest.cpp | 75 +- tests/utility/urlTest.cpp | 100 +- 529 files changed, 25689 insertions(+), 21810 deletions(-) diff --git a/HACKING b/HACKING index f31aa84d..a1cf21ca 100644 --- a/HACKING +++ b/HACKING @@ -80,73 +80,91 @@ width to its preferred settings (eg. 4 or 8 spaces). 2.2. Brace position ------------------- -Open braces should always be at the beginning of the line after the statement -that begins the block. Contents of the brace should be indented by 1 tab. +Open braces should always be at the end of the line of the statement that +begins the block. Contents of the brace should be indented by 1 tab. + + if (expr) { - if (expr) - { do_something(); do_another_thing(); - } - else - { + + } else { + do_something_else(); } +In a function, the opening brace must always be followed by an empty line: + + void header::appendField(const shared_ptr & field) { + + m_fields.push_back(field); + } + +A function with few arguments: + + bool header::hasField(const string& fieldName) const { + + ... + } + +A function with more arguments: + + void header::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition + ) { + + ... + } + 2.3. "switch" statement ----------------------- - switch (expr) - { - case 0: + switch (expr) { - something; - break; + case 0: - case 1: + something; + break; - something_else; - break; + case 1: - case 2: - { - int var = 42; - another_thing; - break; - } + something_else; + break; + case 2: { + + int var = 42; + another_thing; + break; + } } 2.4. Single instruction ----------------------- -Omit braces around simple single-statement body: +Don't omit braces around simple single-statement body: - if (...) + if (...) { something; + } and not: if (...) - { something; - } - -Except when body spans over multiple lines: - - if (...) - { - something_too_long_for( - a_single_line); - } 2.5. Line length ---------------- -Each line of text should not exceed 80 characters. +If possible, each line of text should not exceed 100 characters, except if +manual line wrapping breaks code clarity. Exception: if a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters @@ -290,8 +308,8 @@ Where ever possible, place comments above the code instead of beside it. Comments can be placed at the end of a line when one or more spaces follow. Tabs should NOT be used to indent at the end of a line: - class myClass - { + class myClass { + private: int m_member1; // first member @@ -322,8 +340,8 @@ the purpose of the functions/classes and the meaning of the parameters. * No more than one class per file (except for inner classes). -* Put the inclusion for the class's header file as the first inclusion in - the implementation file. +* Put the #include for the class's header file first in the implementation + file. * Put the copyright header at the top of each file. diff --git a/doc/book/basics.tex b/doc/book/basics.tex index 6dbbff04..94633efd 100644 --- a/doc/book/basics.tex +++ b/doc/book/basics.tex @@ -46,17 +46,17 @@ use the function {\vcode vmime::make\_shared} instead of the {\vcode new} operator. \begin{lstlisting}[caption={Smarts pointers and creating objects}] -class myObject : public vmime::object -{ +class myObject : public vmime::object { + public: myObject(const vmime::string& name) - : m_name(name) - { + : m_name(name) { + } - void sayHello() - { + void sayHello() { + std::cout << "Hello " << m_name << std::endl; } @@ -65,8 +65,8 @@ private: vmime::string m_name; }; -int main() -{ +int main() { + vmime::shared_ptr obj = vmime::make_shared ("world"); @@ -105,12 +105,12 @@ directly or indirectly to itself). The following example illustrates a typical problem of reference counting: \begin{lstlisting} -class parent : public vmime::object -{ +class parent : public vmime::object { + public: - void createChild(vmime::shared_ptr c) - { + void createChild(vmime::shared_ptr c) { + m_child = c; } @@ -119,13 +119,13 @@ private: vmime::shared_ptr m_child; }; -class child : public vmime::object -{ +class child : public vmime::object { + public: child(vmime::shared_ptr p) - : m_parent(p) - { + : m_parent(p) { + } private: @@ -133,8 +133,8 @@ private: vmime::shared_ptr m_parent; }; -int main() -{ +int main() { + vmime::shared_ptr p = vmime::make_shared (); vmime::shared_ptr c = vmime::make_shared (); @@ -179,30 +179,31 @@ Following is an example code for catching VMime exceptions and writing error messages to the console: \begin{lstlisting}[caption={Catching VMime exceptions}] -std::ostream& operator<<(std::ostream& os, const vmime::exception& e) -{ +std::ostream& operator<<(std::ostream& os, const vmime::exception& e) { + os << "* vmime::exceptions::" << e.name() << std::endl; os << " what = " << e.what() << std::endl; // Recursively print all encapsuled exceptions - if (e.other() != NULL) + if (e.other() != NULL) { os << *e.other(); + } return os; } ... -try -{ +try { + // ...some call to VMime... -} -catch (vmime::exception& e) -{ + +} catch (vmime::exception& e) { + std::cerr << e; // VMime exception -} -catch (std::exception& e) -{ + +} catch (std::exception& e) { + std::cerr << e.what(); // standard exception } \end{lstlisting} @@ -250,7 +251,8 @@ vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200"); vmime::datetime d2( /* date */ 2005, vmime::datetime::OCTOBER, 8, /* time */ 14, 7, 52, - /* zone */ vmime::datetime::GMT2); + /* zone */ vmime::datetime::GMT2 +); // Getting day of week const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY @@ -275,7 +277,8 @@ media type with: \begin{lstlisting} vmime::mediaType theType( /* top-level type */ vmime::mediaTypes::IMAGE, - /* sub-type */ vmime::mediaTypes::IMAGE_JPEG); + /* sub-type */ vmime::mediaTypes::IMAGE_JPEG +); // theType.getType() is "image" // theType.getSubType() is "jpeg" @@ -594,8 +597,9 @@ std::ifstream* fileStream = new std::ifstream(); fileStream->open("/home/vincent/paris.jpg", std::ios::binary); -if (!*fileStream) +if (!*fileStream) { // handle error +} vmime::shared_ptr dataStream = vmime::make_shared (fileStream); @@ -608,13 +612,12 @@ vmime::shared_ptr data = vmime::make_shared (dataStream, 0); // Now create the attachment -ref att = vmime::make_shared - ( - /* attachment data */ data, - /* content type */ vmime::mediaType("image/jpeg"), - /* description */ vmime::text("Holiday photo"), - /* filename */ vmime::word("paris.jpg") - ); +ref att = vmime::make_shared ( + /* attachment data */ data, + /* content type */ vmime::mediaType("image/jpeg"), + /* description */ vmime::text("Holiday photo"), + /* filename */ vmime::word("paris.jpg") +); \end{lstlisting} You will see later that the {\vcode vmime::fileAttachment} class already @@ -647,10 +650,11 @@ vmime::shared_ptr cth = body->getContents(); // Then, extract and convert the contents vmime::utility::outputStreamAdapter out(std::cout); -vmime::utility::charsetFilteredOutputStream fout - (/* source charset */ body->getCharset(), +vmime::utility::charsetFilteredOutputStream fout( + /* source charset */ body->getCharset(), /* dest charset */ vmime::charset("utf-8"), - /* dest stream */ out); + /* dest stream */ out +); cth->extract(fout); @@ -778,8 +782,8 @@ vmime::shared_ptr ef = std::cout << "Available encoders:" << std::endl; -for (int i = 0 ; i < ef->getEncoderCount() ; ++i) -{ +for (int i = 0 ; i < ef->getEncoderCount() ; ++i) { + // Output encoder name vmime::shared_ptr enc = ef->getEncoderAt(i); @@ -792,8 +796,9 @@ for (int i = 0 ; i < ef->getEncoderCount() ; ++i) std::vector props = e->getAvailableProperties(); std::vector ::const_iterator it; - for (it = props.begin() ; it != props.end() ; ++it) + for (it = props.begin() ; it != props.end() ; ++it) { std::cout << " - " << *it << std::endl; + } \end{lstlisting} diff --git a/doc/book/intro.tex b/doc/book/intro.tex index 4fa172e9..fe7bcf51 100644 --- a/doc/book/intro.tex +++ b/doc/book/intro.tex @@ -55,7 +55,7 @@ General Public License\footnote{See Appendix \ref{appendix_license} and \url{http://www.gnu.org/copyleft/gpl.html}} (GPL) version 3: \begin{verbatim} - Copyright (C) 2002-2013 Vincent Richard + Copyright (C) 2002 Vincent Richard VMime library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -79,7 +79,7 @@ GNU Free Documentation License\footnote{See \url{http://www.gnu.org/copyleft/fdl.html}} (FDL): \begin{verbatim} - Copyright (C) 2004-2013 Vincent Richard + Copyright (C) 2004 Vincent Richard Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation diff --git a/doc/book/msg.tex b/doc/book/msg.tex index 50344b62..ce9d8a80 100644 --- a/doc/book/msg.tex +++ b/doc/book/msg.tex @@ -94,8 +94,8 @@ vmime::messageParser mp(msg); std::cout << "Message has " << mp.getAttachmentCount() << " attachment(s)" << std::endl; -for (int i = 0 ; i < mp.getAttachmentCount() ; ++i) -{ +for (int i = 0 ; i < mp.getAttachmentCount() ; ++i) { + vmime::shared_ptr att = mp.getAttachmentAt(i); std::cout << " - " << att->getType().generate() << std::endl; } @@ -104,13 +104,13 @@ for (int i = 0 ; i < mp.getAttachmentCount() ; ++i) std::cout << "Message has " << mp.getTextPartCount() << " text part(s)" << std::endl; -for (int i = 0 ; i < mp.getTextPartCount() ; ++i) -{ +for (int i = 0 ; i < mp.getTextPartCount() ; ++i) { + vmime::shared_ptr tp = mp.getTextPartAt(i); // text/html - if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML) - { + if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML) { + vmime::shared_ptr htp = vmime::dynamicCast (tp); @@ -118,18 +118,18 @@ for (int i = 0 ; i < mp.getTextPartCount() ; ++i) // Plain text is in tp->getPlainText() // Enumerate embedded objects - for (int j = 0 ; j < htp->getObjectCount() ; ++j) - { + for (int j = 0 ; j < htp->getObjectCount() ; ++j) { + vmime::shared_ptr obj = htp->getObjectAt(j); // Identifier (Content-Id or Content-Location) is obj->getId() // Object data is in obj->getData() } - } + // text/plain or anything else - else - { + } else { + // Text is in tp->getText() } } @@ -172,8 +172,7 @@ hdr->appendField(subjectField); vmime::shared_ptr fromField = hfFactory->create(vmime::fields::FROM); -fromField->setValue - (vmime::make_shared ("me@vmime.org")); +fromField->setValue(vmime::make_shared ("me@vmime.org")); hdr->appendField(fromField); // Append a 'To:' field @@ -190,8 +189,11 @@ toField->setValue(recipients); hdr->appendField(toField); // Set the body contents -bdy->setContents(vmime::make_shared - ("This is the text of your message...")); +bdy->setContents( + vmime::make_shared ( + "This is the text of your message..." + ) +); // Output raw message data to standard output vmime::utility::outputStreamAdapter out(std::cout); @@ -207,19 +209,23 @@ previous example, using the {\vcode vmime::messageBuilder} object: \begin{lstlisting}[caption={Building a simple message using {\vcode vmime::messageBuilder}}] -try -{ +try { + vmime::messageBuilder mb; // Fill in some header fields and message body mb.setSubject(vmime::text("Message subject")); mb.setExpeditor(vmime::mailbox("me@vmime.org")); - mb.getRecipients().appendAddress - (vmime::make_shared ("you@vmime.org")); + mb.getRecipients().appendAddress( + vmime::make_shared ("you@vmime.org") + ); mb.getTextPart()->setCharset(vmime::charsets::ISO8859_15); - mb.getTextPart()->setText(vmime::make_shared - ("This is the text of your message...")); + mb.getTextPart()->setText( + vmime::make_shared ( + "This is the text of your message..." + ) + ); // Message construction vmime::shared_ptr msg = mb.construct(); @@ -227,15 +233,15 @@ try // Output raw message data to standard output vmime::utility::outputStreamAdapter out(std::cout); msg->generate(out); -} + // VMime exception -catch (vmime::exception& e) -{ +} catch (vmime::exception& e) { + std::cerr << "vmime::exception: " << e.what() << std::endl; -} + // Standard exception -catch (std::exception& e) -{ +} catch (std::exception& e) { + std::cerr << "std::exception: " << e.what() << std::endl; } \end{lstlisting} @@ -250,17 +256,17 @@ previous example to attach a file to the message: {\vcode vmime::messageBuilder}}] // Create an attachment vmime::shared_ptr att = - vmime::make_shared - ( - /* full path to file */ "/home/vincent/paris.jpg", - /* content type */ vmime::mediaType("image/jpeg), - /* description */ vmime::text("My holidays in Paris") + vmime::make_shared ( + /* full path to file */ "/home/vincent/paris.jpg", + /* content type */ vmime::mediaType("image/jpeg), + /* description */ vmime::text("My holidays in Paris") ); // You can also set some infos about the file att->getFileInfo().setFilename("paris.jpg"); -att->getFileInfo().setCreationDate - (vmime::datetime("30 Apr 2003 14:30:00 +0200")); +att->getFileInfo().setCreationDate( + vmime::datetime("30 Apr 2003 14:30:00 +0200") +); // Add this attachment to the message mb.appendAttachment(att); @@ -283,14 +289,19 @@ using the {\vcode vmime::messageBuilder}}] // Fill in some header fields mb.setSubject(vmime::text("An HTML message")); mb.setExpeditor(vmime::mailbox("me@vmime.org")); -mb.getRecipients().appendAddress - (vmime::make_shared ("you@vmime.org")); +mb.getRecipients().appendAddress( + vmime::make_shared ("you@vmime.org") +); // Set the content-type to "text/html": a text part factory must be // available for the type you are using. The following code will make // the message builder construct the two text parts. -mb.constructTextPart(vmime::mediaType - (vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML)); +mb.constructTextPart( + vmime::mediaType( + vmime::mediaTypes::TEXT, + vmime::mediaTypes::TEXT_HTML + ) +); // Set contents of the text parts; the message is available in two formats: // HTML and plain text. The HTML format also includes an embedded image. @@ -306,12 +317,18 @@ const vmime::string id = textPart->addObject("<...image data...>", // -- Set the text textPart->setCharset(vmime::charsets::ISO8859_15); -textPart->setText(vmime::make_shared - ("This is the HTML text, and the image:
" - "")); +textPart->setText( + vmime::make_shared ( + "This is the HTML text, and the image:
" + "" + ) +); -textPart->setPlainText(vmime::make_shared - ("This is the plain text.")); +textPart->setPlainText( + vmime::make_shared ( + "This is the plain text." + ) +); \end{lstlisting} This will create a message having the following structure: @@ -336,11 +353,18 @@ vmime::shared_ptr imageFile = fs->create(fs->stringToPath("/path/to/image.jpg")); vmime::shared_ptr imageCts = - vmime::make_shared - (imageFile->getFileReader()->getInputStream(), imageFile->getLength()); + vmime::make_shared ( + imageFile->getFileReader()->getInputStream(), + imageFile->getLength() + ); -const vmime::string cid = textPart.addObject(imageCts, - vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG)); +const vmime::string cid = textPart.addObject( + imageCts, + vmime::mediaType( + vmime::mediaTypes::IMAGE, + vmime::mediaTypes::IMAGE_JPEG + ) +); \end{lstlisting} @@ -361,8 +385,8 @@ extract its contents to the standard output: \begin{lstlisting}[caption={Testing if a body part is an attachment}] vmime::shared_ptr part; // suppose we have a body part -if (vmime::attachmentHelper::isBodyPartAnAttachment(part)) -{ +if (vmime::attachmentHelper::isBodyPartAnAttachment(part)) { + // The body part contains an attachment, get it vmime::shared_ptr attach = attachmentHelper::getBodyPartAttachment(part); @@ -394,11 +418,10 @@ vmime::shared_ptr msg; // suppose we have a message // Create an attachment vmime::shared_ptr att = - vmime::make_shared - ( - /* full path to file */ "/home/vincent/paris.jpg", - /* content type */ vmime::mediaType("image/jpeg), - /* description */ vmime::text("My holidays in Paris") + vmime::make_shared ( + /* full path to file */ "/home/vincent/paris.jpg", + /* content type */ vmime::mediaType("image/jpeg), + /* description */ vmime::text("My holidays in Paris") ); // Attach it to the message diff --git a/doc/book/net.tex b/doc/book/net.tex index 301e3f11..3fab903a 100644 --- a/doc/book/net.tex +++ b/doc/book/net.tex @@ -300,10 +300,10 @@ The following example shows how to use a custom authenticator to request the user to enter her/his credentials: \begin{lstlisting}[caption={A simple interactive authenticator}] -class myAuthenticator : public vmime::security::defaultAuthenticator -{ - const string getUsername() const - { +class myAuthenticator : public vmime::security::defaultAuthenticator { + + const string getUsername() const { + std::cout << "Enter your username: " << std::endl; vmime::string res; @@ -312,8 +312,8 @@ class myAuthenticator : public vmime::security::defaultAuthenticator return res; } - const string getPassword() const - { + const string getPassword() const { + std::cout << "Enter your password: " << std::endl; vmime::string res; @@ -331,9 +331,10 @@ This is how to use it: vmime::shared_ptr sess = vmime::net::session::create(); // Next, initialize a service which will use our authenticator -vmime::shared_ptr st = - sess->getStore(vmime::utility::url("imap://imap.example.com"), - /* use our authenticator */ vmime::make_shared ()); +vmime::shared_ptr st = sess->getStore( + vmime::utility::url("imap://imap.example.com"), + /* use our authenticator */ vmime::make_shared () +); \end{lstlisting} \vnote{An authenticator object should be used with one and only one service @@ -354,14 +355,15 @@ use the SASL-specific methods {\vcode getAcceptableMechanisms()} and implementation of an SASL authenticator. \begin{lstlisting}[caption={A simple SASL authenticator}] -class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator -{ +class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator { + typedef vmime::security::sasl::SASLMechanism mechanism; // save us typing - const std::vector > getAcceptableMechanisms - (const std::vector >& available, - const vmime::shared_ptr & suggested) const - { + const std::vector > getAcceptableMechanisms( + const std::vector >& available, + const vmime::shared_ptr & suggested + ) const { + // Here, you can sort the SASL mechanisms in the order they will be // tried. If no SASL mechanism is acceptable (ie. for example, not // enough secure), you can return an empty list. @@ -372,8 +374,8 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat getAcceptableMechanisms(available, suggested); } - void setSASLMechanism(const vmime::shared_ptr & mech) - { + void setSASLMechanism(const vmime::shared_ptr & mech) { + // This is called when the authentication process is going to // try the specified mechanism. // @@ -435,7 +437,8 @@ tr->send( /* expeditor */ from, /* recipient(s) */ to, /* data */ is, - /* total length */ msgData.length()); + /* total length */ msgData.length() +); // We have finished using the service tr->disconnect(); @@ -556,22 +559,26 @@ std::vector > allMessages = folder->getMessages(vmime::net::messageSet::byNumber(1, -1)); // -1 is a special value to mean "the number of the last message in the folder" -folder->fetchMessages(allMessages, +folder->fetchMessages( + allMessages, vmime::net::fetchAttributes::FLAGS | - vmime::net::fetchAttributes::ENVELOPE); + vmime::net::fetchAttributes::ENVELOPE +); + +for (unsigned int i = 0 ; i < allMessages.size() ; ++i) { -for (unsigned int i = 0 ; i < allMessages.size() ; ++i) -{ vmime::shared_ptr msg = allMessages[i]; const int flags = msg->getFlags(); std::cout << "Message " << i << ":" << std::endl; - if (flags & vmime::net::message::FLAG_SEEN) + if (flags & vmime::net::message::FLAG_SEEN) { std::cout << " - is read" << std::endl; - if (flags & vmime::net::message::FLAG_DELETED) + } + if (flags & vmime::net::message::FLAG_DELETED) { std::cout << " - is deleted" << std::endl; + } vmime::shared_ptr hdr = msg->getHeader(); @@ -698,8 +705,8 @@ running. An interface called {\vcode timeoutHandler} is provided: \begin{lstlisting} -class timeoutHandler : public object -{ +class timeoutHandler : public object { + /** Called to test if the time limit has been reached. * * @return true if the timeout delay is elapsed @@ -738,27 +745,27 @@ is thrown. The following example shows how to implement a simple timeout handler: \begin{lstlisting}[caption={Implementing a simple timeout handler}] -class myTimeoutHandler : public vmime::net::timeoutHandler -{ +class myTimeoutHandler : public vmime::net::timeoutHandler { + public: - myTimeoutHandler() - { + myTimeoutHandler() { + m_startTime = time(NULL); } - const bool isTimeOut() - { - return (time(NULL) >= m_startTime + 30); // 30 seconds timeout + const bool isTimeOut() { + + return time(NULL) >= m_startTime + 30; // 30 seconds timeout } - void resetTimeOut() - { + void resetTimeOut() { + m_startTime = time(NULL); } - const bool handleTimeOut() - { + const bool handleTimeOut() { + std::cout << "Operation timed out." << std::endl; << "Press [Y] to continue, or [N] to " << "cancel the operation." << std::endl; @@ -766,7 +773,7 @@ public: std::string response; std::cin >> response; - return (response == "y" || response == "Y"); + return response == "y" || response == "Y"; } private: @@ -781,12 +788,12 @@ is required because the service can use several connections to the server simultaneously, and each connection needs its own timeout handler. \begin{lstlisting} -class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory -{ +class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory { + public: - ref create() - { + ref create() { + return vmime::make_shared (); } }; @@ -918,13 +925,12 @@ First, we need some code to load existing X.509 certificates: \begin{lstlisting}[caption={Reading a X.509 certificate from a file}] vmime::shared_ptr - loadX509CertificateFromFile(const std::string& path) -{ + loadX509CertificateFromFile(const std::string& path) { + std::ifstream certFile; certFile.open(path.c_str(), std::ios::in | std::ios::binary); - if (!certFile) - { + if (!certFile) { // ...handle error... } @@ -978,12 +984,12 @@ use this in a production application as this is obviously a serious security issue): \begin{lstlisting}[caption={A custom certificate verifier}] -class myCertVerifier : public vmime::security::cert::certificateVerifier -{ +class myCertVerifier : public vmime::security::cert::certificateVerifier { + public: - void verify(const vmime::shared_ptr & certs) - { + void verify(const vmime::shared_ptr & certs) { + // Obtain the subject's certificate vmime::shared_ptr cert = chain->getAt(0); @@ -996,8 +1002,9 @@ public: std::string answer; std::getline(std::cin, answer); - if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y')) + if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y')) { return; // OK, we trust the certificate + } // Don't trust this certificate throw vmime::security::cert::certificateException(); @@ -1092,25 +1099,26 @@ First, you have to create your own tracer, which must implement the simply logs to the standard output: \begin{lstlisting}[caption={A simple tracer}] -class myTracer : public vmime::net::tracer -{ +class myTracer : public vmime::net::tracer { + public: myTracer(const vmime::string& proto, const int connectionId) - : m_proto(proto), m_connectionId(connectionId) - { + : m_proto(proto), + m_connectionId(connectionId) { + } // Called by VMime to trace what is sent on the socket - void traceSend(const vmime::string& line) - { + void traceSend(const vmime::string& line) { + std::cout << "[" << m_proto << ":" << m_connectionId << "] C: " << line << std::endl; } // Called by VMime to trace what is received from the socket - void traceReceive(const vmime::string& line) - { + void traceReceive(const vmime::string& line) { + std::cout << "[" < < m_proto << ":" << m_connectionId << "] S: " << line << std::endl; } @@ -1125,16 +1133,18 @@ private: Also create a factory class, used to instanciate your tracer objects: \begin{lstlisting} -class myTracerFactory : public vmime::net::tracerFactory -{ +class myTracerFactory : public vmime::net::tracerFactory { + public: - vmime::shared_ptr create - (const vmime::shared_ptr & serv, - const int connectionId) - { - return vmime::make_shared - (serv->getProtocolName(), connectionId); + vmime::shared_ptr create( + const vmime::shared_ptr & serv, + const int connectionId + ) { + + return vmime::make_shared ( + serv->getProtocolName(), connectionId + ); } }; \end{lstlisting} diff --git a/doc/book/start.tex b/doc/book/start.tex index 74084941..f1693301 100644 --- a/doc/book/start.tex +++ b/doc/book/start.tex @@ -82,8 +82,8 @@ So, if your platform is POSIX, your program should look like this: #include #include -int main() -{ +int main() { + vmime::platform:: setHandler (); diff --git a/examples/example1.cpp b/examples/example1.cpp index b80fe636..c698fa7f 100644 --- a/examples/example1.cpp +++ b/examples/example1.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,23 +39,20 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + std::cout << std::endl; // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - try - { + try { + vmime::messageBuilder mb; // Fill in the basic fields @@ -74,9 +71,12 @@ int main() mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); // Message body - mb.getTextPart()->setText(vmime::make_shared ( - "I'm writing this short text to test message construction " \ - "using the vmime::messageBuilder component.")); + mb.getTextPart()->setText( + vmime::make_shared ( + "I'm writing this short text to test message construction " \ + "using the vmime::messageBuilder component." + ) + ); // Construction vmime::shared_ptr msg = mb.construct(); @@ -87,20 +87,21 @@ int main() vmime::utility::outputStreamAdapter out(std::cout); msg->generate(out); - } + // VMime exception - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { + std::cout << "vmime::exception: " << e.what() << std::endl; throw; - } + // Standard exception - catch (std::exception& e) - { + } catch (std::exception& e) { + std::cout << "std::exception: " << e.what() << std::endl; - //throw; + throw; } std::cout << std::endl; -} + return 0; +} diff --git a/examples/example2.cpp b/examples/example2.cpp index 67b8d844..da01d756 100644 --- a/examples/example2.cpp +++ b/examples/example2.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,23 +39,20 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + std::cout << std::endl; // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - try - { + try { + vmime::messageBuilder mb; // Fill in the basic fields @@ -74,17 +71,20 @@ int main() mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); // Message body - mb.getTextPart()->setText(vmime::make_shared ( - "I'm writing this short text to test message construction " \ - "with attachment, using the vmime::messageBuilder component.")); + mb.getTextPart()->setText( + vmime::make_shared ( + "I'm writing this short text to test message construction " \ + "with attachment, using the vmime::messageBuilder component." + ) + ); // Adding an attachment - vmime::shared_ptr a = vmime::make_shared - ( - __FILE__, // full path to file - vmime::mediaType("application/octet-stream"), // content type - vmime::text("My first attachment") // description - ); + vmime::shared_ptr a = + vmime::make_shared ( + __FILE__, // full path to file + vmime::mediaType("application/octet-stream"), // content type + vmime::text("My first attachment") // description + ); a->getFileInfo().setFilename("example2.cpp"); a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200")); @@ -101,20 +101,21 @@ int main() std::cout << "==================" << std::endl; std::cout << std::endl; std::cout << dataToSend << std::endl; - } + // VMime exception - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { + std::cout << "vmime::exception: " << e.what() << std::endl; throw; - } + // Standard exception - catch (std::exception& e) - { + } catch (std::exception& e) { + std::cout << "std::exception: " << e.what() << std::endl; throw; } std::cout << std::endl; -} + return 0; +} diff --git a/examples/example3.cpp b/examples/example3.cpp index a472e05c..b4522256 100644 --- a/examples/example3.cpp +++ b/examples/example3.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,23 +39,20 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + std::cout << std::endl; // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - try - { + try { + vmime::messageBuilder mb; // Fill in the basic fields @@ -74,12 +71,17 @@ int main() mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder")); // Set the content-type to "text/html" - mb.constructTextPart(vmime::mediaType - (vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML)); + mb.constructTextPart( + vmime::mediaType( + vmime::mediaTypes::TEXT, + vmime::mediaTypes::TEXT_HTML + ) + ); // Fill in the text part: the message is available in two formats: HTML and plain text. // HTML text part also includes an inline image (embedded into the message). - vmime::htmlTextPart& textPart = *vmime::dynamicCast (mb.getTextPart()); + vmime::htmlTextPart& textPart = + *vmime::dynamicCast (mb.getTextPart()); // -- embed an image (the returned "CID" (content identifier) is used to reference // -- the image into HTML content). @@ -93,18 +95,33 @@ int main() imageFile->getFileReader(); vmime::shared_ptr imageCts = - vmime::make_shared - (fileReader->getInputStream(), imageFile->getLength()); + vmime::make_shared ( + fileReader->getInputStream(), + imageFile->getLength() + ); - vmime::shared_ptr obj = textPart.addObject - (imageCts, vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG)); + vmime::shared_ptr obj = + textPart.addObject( + imageCts, + vmime::mediaType( + vmime::mediaTypes::IMAGE, + vmime::mediaTypes::IMAGE_JPEG + ) + ); // -- message text - textPart.setText(vmime::make_shared - (vmime::string("This is the HTML text.
" - "getReferenceId() + vmime::string("\"/>"))); - textPart.setPlainText(vmime::make_shared - ("This is the plain text (without HTML formatting).")); + textPart.setText( + vmime::make_shared ( + vmime::string("This is the HTML text.
" + "getReferenceId() + vmime::string("\"/>") + ) + ); + + textPart.setPlainText( + vmime::make_shared ( + "This is the plain text (without HTML formatting)." + ) + ); // Construction vmime::shared_ptr msg = mb.construct(); @@ -116,20 +133,21 @@ int main() std::cout << "==================" << std::endl; std::cout << std::endl; std::cout << dataToSend << std::endl; - } + // VMime exception - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { + std::cout << "vmime::exception: " << e.what() << std::endl; throw; - } + // Standard exception - catch (std::exception& e) - { + } catch (std::exception& e) { + std::cout << "std::exception: " << e.what() << std::endl; throw; } std::cout << std::endl; -} + return 0; +} diff --git a/examples/example4.cpp b/examples/example4.cpp index 1e0d6657..4d50c2e4 100644 --- a/examples/example4.cpp +++ b/examples/example4.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,71 +39,70 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + std::cout << std::endl; // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - try - { + try { + vmime::messageParser mp("<...MIME message content...>"); // Enumerate text parts - for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i) - { + for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i) { + const vmime::textPart& part = *mp.getTextPartAt(i); // Output content-type of the part std::cout << part.getType().generate() << std::endl; // text/html - if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML) - { + if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML) { + const vmime::htmlTextPart& hp = dynamic_cast(part); // HTML text is in "hp.getText()" // Corresponding plain text is in "hp.getPlainText()" // Enumerate embedded objects (eg. images) - for (size_t j = 0 ; j < hp.getObjectCount() ; ++j) - { + for (size_t j = 0 ; j < hp.getObjectCount() ; ++j) { + const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j); // Identifier (content-id or content-location) is in "obj.getId()" // Object data is in "obj.getData()" } - } + // text/plain - else - { + } else { + const vmime::textPart& tp = dynamic_cast(part); // Text is in "tp.getText()" } } - } + // VMime exception - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { + std::cout << "vmime::exception: " << e.what() << std::endl; throw; - } + // Standard exception - catch (std::exception& e) - { + } catch (std::exception& e) { + std::cout << "std::exception: " << e.what() << std::endl; throw; } std::cout << std::endl; + + return 0; } diff --git a/examples/example5.cpp b/examples/example5.cpp index d33c64f7..24d5cbfc 100644 --- a/examples/example5.cpp +++ b/examples/example5.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,28 +39,25 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + std::cout << std::endl; // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - try - { + try { + vmime::messageParser mp("<...MIME message content...>"); // Enumerate attachments - for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i) - { + for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i) { + const vmime::attachment& att = *mp.getAttachmentAt(i); // Media type (content type) is in "att.getType()" @@ -68,19 +65,21 @@ int main() // Description is in "att.getDescription()" // Data is in "att.getData()" } - } + // VMime exception - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { + std::cout << "vmime::exception: " << e.what() << std::endl; throw; - } + // Standard exception - catch (std::exception& e) - { + } catch (std::exception& e) { + std::cout << "std::exception: " << e.what() << std::endl; throw; } std::cout << std::endl; + + return 0; } diff --git a/examples/example6.cpp b/examples/example6.cpp index 91a5ba5d..add24b38 100644 --- a/examples/example6.cpp +++ b/examples/example6.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,22 +46,23 @@ static vmime::shared_ptr g_session = vmime::net::session:: * @param type service type (vmime::net::service::TYPE_STORE or * vmime::net::service::TYPE_TRANSPORT) */ -static const std::string findAvailableProtocols(const vmime::net::service::Type type) -{ +static const std::string findAvailableProtocols(const vmime::net::service::Type type) { + vmime::shared_ptr sf = vmime::net::serviceFactory::getInstance(); std::ostringstream res; size_t count = 0; - for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) - { + for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) { + const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i); - if (serv.getType() == type) - { - if (count != 0) + if (serv.getType() == type) { + + if (count != 0) { res << ", "; + } res << serv.getName(); ++count; @@ -73,14 +74,14 @@ static const std::string findAvailableProtocols(const vmime::net::service::Type // Exception helper -static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) -{ +static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) { + os << "* vmime::exceptions::" << e.name() << std::endl; os << " what = " << e.what() << std::endl; // More information for special exceptions - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::command_error& cee = dynamic_cast (e); @@ -88,32 +89,32 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) os << " response = " << cee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::invalid_response& ir = dynamic_cast (e); os << " response = " << ir.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::connection_greeting_error& cgee = dynamic_cast (e); os << " response = " << cgee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::authentication_error& aee = dynamic_cast (e); os << " response = " << aee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::filesystem_exception& fse = dynamic_cast (e); @@ -121,8 +122,9 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) getFileSystemFactory()->pathToString(fse.path()) << std::endl; } - if (e.other() != NULL) + if (e.other()) { os << *e.other(); + } return os; } @@ -133,35 +135,40 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) * @param s structure object * @param level current depth */ -static void printStructure(vmime::shared_ptr s, const int level = 0) -{ - for (size_t i = 0 ; i < s->getPartCount() ; ++i) - { +static void printStructure( + vmime::shared_ptr s, + const int level = 0 +) { + + for (size_t i = 0 ; i < s->getPartCount() ; ++i) { + vmime::shared_ptr part = s->getPartAt(i); - for (int j = 0 ; j < level * 2 ; ++j) + for (int j = 0 ; j < level * 2 ; ++j) { std::cout << " "; + } - std::cout << (part->getNumber() + 1) << ". " - << part->getType().generate() - << " [" << part->getSize() << " byte(s)]" - << std::endl; + std::cout + << (part->getNumber() + 1) << ". " + << part->getType().generate() + << " [" << part->getSize() << " byte(s)]" + << std::endl; printStructure(part->getStructure(), level + 1); } } -static const vmime::string getFolderPathString(vmime::shared_ptr f) -{ +static const vmime::string getFolderPathString(vmime::shared_ptr f) { + const vmime::string n = f->getName().getBuffer(); - if (n.empty()) // root folder - { + if (n.empty()) { // root folder + return "/"; - } - else - { + + } else { + vmime::shared_ptr p = f->getParent(); return getFolderPathString(p) + n + "/"; } @@ -172,38 +179,43 @@ static const vmime::string getFolderPathString(vmime::shared_ptr folder, const int level = 0) -{ - for (int j = 0 ; j < level * 2 ; ++j) +static void printFolders(vmime::shared_ptr folder, const int level = 0) { + + for (int j = 0 ; j < level * 2 ; ++j) { std::cout << " "; + } const vmime::net::folderAttributes attr = folder->getAttributes(); std::ostringstream attrStr; - if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) + if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) { attrStr << " \\use:All"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) { attrStr << " \\use:Archive"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS) { attrStr << " \\use:Drafts"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED) { attrStr << " \\use:Flagged"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK) { attrStr << " \\use:Junk"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT) { attrStr << " \\use:Sent"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH) { attrStr << " \\use:Trash"; - else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) + } else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) { attrStr << " \\use:Important"; + } - if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) { attrStr << " \\flag:HasChildren"; - if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) + } + if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) { attrStr << " \\flag:NoOpen"; + } - for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i) + for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i) { attrStr << " \\" << attr.getUserFlags()[i]; + } std::cout << getFolderPathString(folder); std::cout << " " << attrStr.str(); @@ -211,8 +223,9 @@ static void printFolders(vmime::shared_ptr folder, const in std::vector > subFolders = folder->getFolders(false); - for (unsigned int i = 0 ; i < subFolders.size() ; ++i) + for (unsigned int i = 0 ; i < subFolders.size() ; ++i) { printFolders(subFolders[i], level + 1); + } } @@ -220,12 +233,13 @@ static void printFolders(vmime::shared_ptr folder, const in * * @param choices menu choices */ -static unsigned int printMenu(const std::vector & choices) -{ +static unsigned int printMenu(const std::vector & choices) { + std::cout << std::endl; - for (unsigned int i = 0 ; i < choices.size() ; ++i) + for (unsigned int i = 0 ; i < choices.size() ; ++i) { std::cout << " " << (i + 1) << ". " << choices[i] << std::endl; + } std::cout << std::endl; std::cout << " Your choice? [1-" << choices.size() << "] "; @@ -241,19 +255,20 @@ static unsigned int printMenu(const std::vector & choices) std::cout << std::endl; - if (choice < 1 || choice > choices.size()) + if (choice < 1 || choice > choices.size()) { return 0; - else + } else { return choice; + } } /** Send a message interactively. */ -static void sendMessage() -{ - try - { +static void sendMessage() { + + try { + // Request user to enter an URL std::cout << "Enter an URL to connect to transport service." << std::endl; std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl; @@ -268,10 +283,11 @@ static void sendMessage() vmime::shared_ptr tr; - if (url.getUsername().empty() || url.getPassword().empty()) + if (url.getUsername().empty() || url.getPassword().empty()) { tr = g_session->getTransport(url, vmime::make_shared ()); - else + } else { tr = g_session->getTransport(url); + } #if VMIME_HAVE_TLS_SUPPORT @@ -283,15 +299,17 @@ static void sendMessage() // Set the object responsible for verifying certificates, in the // case a secured connection is used (TLS/SSL) - tr->setCertificateVerifier - (vmime::make_shared ()); + tr->setCertificateVerifier( + vmime::make_shared () + ); #endif // VMIME_HAVE_TLS_SUPPORT // You can also set some properties (see example7 to know the properties // available for each service). For example, for SMTP: - if (!url.getUsername().empty() || !url.getPassword().empty()) + if (!url.getUsername().empty() || !url.getPassword().empty()) { tr->setProperty("options.need-authentication", true); + } // Trace communication between client and server vmime::shared_ptr traceStream = vmime::make_shared (); @@ -307,8 +325,8 @@ static void sendMessage() vmime::mailbox from(fromString); vmime::mailboxList to; - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + std::cout << "Enter email of the recipient (empty to stop): "; std::cout.flush(); @@ -317,23 +335,25 @@ static void sendMessage() cont = (toString.size() != 0); - if (cont) + if (cont) { to.appendMailbox(vmime::make_shared (toString)); + } } std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl; std::ostringstream data; - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + std::string line; std::getline(std::cin, line); - if (line == ".") + if (line == ".") { cont = false; - else + } else { data << line << "\r\n"; + } } // Connect to server @@ -357,15 +377,15 @@ static void sendMessage() std::cout << traceStream->str(); tr->disconnect(); - } - catch (vmime::exception& e) - { + + } catch (vmime::exception& e) { + std::cerr << std::endl; std::cerr << e << std::endl; throw; - } - catch (std::exception& e) - { + + } catch (std::exception& e) { + std::cerr << std::endl; std::cerr << "std::exception: " << e.what() << std::endl; throw; @@ -375,10 +395,10 @@ static void sendMessage() /** Connect to a message store interactively. */ -static void connectStore() -{ - try - { +static void connectStore() { + + try { + // Request user to enter an URL std::cout << "Enter an URL to connect to store service." << std::endl; std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl; @@ -396,10 +416,11 @@ static void connectStore() // session properties "auth.username" and "auth.password". vmime::shared_ptr st; - if (url.getUsername().empty() || url.getPassword().empty()) + if (url.getUsername().empty() || url.getPassword().empty()) { st = g_session->getStore(url, vmime::make_shared ()); - else + } else { st = g_session->getStore(url); + } #if VMIME_HAVE_TLS_SUPPORT @@ -411,8 +432,9 @@ static void connectStore() // Set the object responsible for verifying certificates, in the // case a secured connection is used (TLS/SSL) - st->setCertificateVerifier - (vmime::make_shared ()); + st->setCertificateVerifier( + vmime::make_shared () + ); #endif // VMIME_HAVE_TLS_SUPPORT @@ -441,13 +463,13 @@ static void connectStore() std::cout << std::endl; std::cout << count << " message(s) in your inbox" << std::endl; - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + typedef std::map > MessageList; MessageList msgList; - try - { + try { + std::vector choices; choices.push_back("Show message flags"); @@ -470,8 +492,8 @@ static void connectStore() vmime::shared_ptr msg; if (choice == 1 || choice == 2 || choice == 3 || choice == 4 || - choice == 5 || choice == 6 || choice == 11) - { + choice == 5 || choice == 6 || choice == 11) { + std::cout << "Enter message number: "; std::cout.flush(); @@ -483,20 +505,20 @@ static void connectStore() vmime::size_t num = 0; iss >> num; - if (num < 1 || num > f->getMessageCount()) - { + if (num < 1 || num > f->getMessageCount()) { + std::cerr << "Invalid message number." << std::endl; continue; } MessageList::iterator it = msgList.find(num); - if (it != msgList.end()) - { + if (it != msgList.end()) { + msg = (*it).second; - } - else - { + + } else { + msg = f->getMessage(num); msgList.insert(MessageList::value_type(num, msg)); } @@ -504,25 +526,31 @@ static void connectStore() std::cout << std::endl; } - switch (choice) - { + switch (choice) { + // Show message flags case 1: f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS); - if (msg->getFlags() & vmime::net::message::FLAG_SEEN) + if (msg->getFlags() & vmime::net::message::FLAG_SEEN) { std::cout << "FLAG_SEEN" << std::endl; - if (msg->getFlags() & vmime::net::message::FLAG_RECENT) + } + if (msg->getFlags() & vmime::net::message::FLAG_RECENT) { std::cout << "FLAG_RECENT" << std::endl; - if (msg->getFlags() & vmime::net::message::FLAG_REPLIED) + } + if (msg->getFlags() & vmime::net::message::FLAG_REPLIED) { std::cout << "FLAG_REPLIED" << std::endl; - if (msg->getFlags() & vmime::net::message::FLAG_DELETED) + } + if (msg->getFlags() & vmime::net::message::FLAG_DELETED) { std::cout << "FLAG_DELETED" << std::endl; - if (msg->getFlags() & vmime::net::message::FLAG_MARKED) + } + if (msg->getFlags() & vmime::net::message::FLAG_MARKED) { std::cout << "FLAG_MARKED" << std::endl; - if (msg->getFlags() & vmime::net::message::FLAG_PASSED) + } + if (msg->getFlags() & vmime::net::message::FLAG_PASSED) { std::cout << "FLAG_PASSED" << std::endl; + } break; @@ -541,8 +569,8 @@ static void connectStore() break; // Show message envelope - case 4: - { + case 4: { + vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE); // If you also want to fetch "Received: " fields: @@ -555,37 +583,38 @@ static void connectStore() break; } // Extract whole message - case 5: - { + case 5: { + vmime::utility::outputStreamAdapter out(std::cout); msg->extract(out); break; } // Extract attachments - case 6: - { + case 6: { + vmime::shared_ptr parsedMsg = msg->getParsedMessage(); std::vector > attchs = vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg); - if (attchs.size() > 0) - { + if (attchs.size() > 0) { + std::cout << attchs.size() << " attachments found." << std::endl; for (std::vector >::iterator - it = attchs.begin() ; it != attchs.end() ; ++it) - { + it = attchs.begin() ; it != attchs.end() ; ++it) { + vmime::shared_ptr att = *it; // Get attachment size vmime::size_t size = 0; - if (att->getData()->isEncoded()) + if (att->getData()->isEncoded()) { size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength()); - else + } else { size = att->getData()->getLength(); + } std::cout << "Found attachment '" << att->getName().getBuffer() << "'" << ", size is " << size << " bytes:" << std::endl; @@ -618,17 +647,17 @@ static void connectStore() att->getData()->extract(*output.get()); */ } - } - else - { + + } else { + std::cout << "No attachments found." << std::endl; } break; } // Status - case 7: - { + case 7: { + vmime::size_t count, unseen; f->status(count, unseen); @@ -636,17 +665,16 @@ static void connectStore() break; } // List folders - case 8: - { - vmime::shared_ptr - root = st->getRootFolder(); + case 8: { + + vmime::shared_ptr root = st->getRootFolder(); printFolders(root); break; } // Change folder - case 9: - { + case 9: { + std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl; std::cout.flush(); @@ -655,19 +683,21 @@ static void connectStore() vmime::shared_ptr newFolder = st->getRootFolder(); - for (std::string::size_type s = 0, p = 0 ; ; s = p + 1) - { + for (std::string::size_type s = 0, p = 0 ; ; s = p + 1) { + p = path.find_first_of('/', s); const std::string x = (p == std::string::npos) ? std::string(path.begin() + s, path.end()) : std::string(path.begin() + s, path.begin() + p); - if (!x.empty()) + if (!x.empty()) { newFolder = newFolder->getFolder(vmime::utility::path::component(x)); + } - if (p == std::string::npos) + if (p == std::string::npos) { break; + } } newFolder->open(vmime::net::folder::MODE_READ_WRITE); @@ -683,8 +713,8 @@ static void connectStore() break; } // Add message - case 10: - { + case 10: { + vmime::messageBuilder mb; mb.setExpeditor(vmime::mailbox("me@somewhere.com")); @@ -694,32 +724,35 @@ static void connectStore() mb.setRecipients(to); mb.setSubject(vmime::text("Test message from VMime example6")); - mb.getTextPart()->setText(vmime::make_shared ( - "Body of test message from VMime example6.")); + mb.getTextPart()->setText( + vmime::make_shared ( + "Body of test message from VMime example6." + ) + ); vmime::shared_ptr msg = mb.construct(); vmime::net::messageSet set = f->addMessage(msg); - if (set.isEmpty()) - { + if (set.isEmpty()) { + std::cout << "Message has successfully been added, " << "but its UID/number is not known." << std::endl; - } - else - { + + } else { + const vmime::net::messageRange& range = set.getRangeAt(0); - if (set.isUIDSet()) - { + if (set.isUIDSet()) { + const vmime::net::message::uid uid = dynamic_cast (range).getFirst(); std::cout << "Message has successfully been added, " << "its UID is '" << uid << "'." << std::endl; - } - else - { + + } else { + const vmime::size_t number = dynamic_cast (range).getFirst(); @@ -731,30 +764,30 @@ static void connectStore() break; } // Copy message - case 11: - { + case 11: { + vmime::net::messageSet set = f->copyMessages(f->getFullPath(), vmime::net::messageSet::byNumber(msg->getNumber())); - if (set.isEmpty()) - { + if (set.isEmpty()) { + std::cout << "Message has successfully been copied, " << "but its UID/number is not known." << std::endl; - } - else - { + + } else { + const vmime::net::messageRange& range = set.getRangeAt(0); - if (set.isUIDSet()) - { + if (set.isUIDSet()) { + const vmime::net::message::uid uid = dynamic_cast (range).getFirst(); std::cout << "Message has successfully been copied, " << "its UID is '" << uid << "'." << std::endl; - } - else - { + + } else { + const vmime::size_t number = dynamic_cast (range).getFirst(); @@ -808,35 +841,37 @@ static void connectStore() { vmime::shared_ptr g = st->getFolder(vmime::net::folder::path("TEMP")); - if (!g->exists()) + if (!g->exists()) { g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES); + } f->copyMessages(g->getFullPath()); } */ - } - catch (vmime::exception& e) - { + + } catch (vmime::exception& e) { + std::cerr << std::endl; std::cerr << e << std::endl; - } - catch (std::exception& e) - { + + } catch (std::exception& e) { + std::cerr << std::endl; std::cerr << "std::exception: " << e.what() << std::endl; } + } // for(cont) st->disconnect(); - } - catch (vmime::exception& e) - { + + } catch (vmime::exception& e) { + std::cerr << std::endl; std::cerr << e << std::endl; throw; - } - catch (std::exception& e) - { + + } catch (std::exception& e) { + std::cerr << std::endl; std::cerr << "std::exception: " << e.what() << std::endl; throw; @@ -848,16 +883,16 @@ static void connectStore() * * @return true to quit the program, false to continue */ -static bool menu() -{ +static bool menu() { + std::vector items; items.push_back("Connect to a message store"); items.push_back("Send a message"); items.push_back("Quit"); - switch (printMenu(items)) - { + switch (printMenu(items)) { + // Connect to store case 1: @@ -883,25 +918,21 @@ static bool menu() } -int main() -{ +int main() { + // 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } - for (bool quit = false ; !quit ; ) - { + for (bool quit = false ; !quit ; ) { + // Loop on main menu quit = menu(); } return 0; } - diff --git a/examples/example6_authenticator.hpp b/examples/example6_authenticator.hpp index 64336e2a..56f02392 100644 --- a/examples/example6_authenticator.hpp +++ b/examples/example6_authenticator.hpp @@ -3,20 +3,23 @@ #if VMIME_HAVE_SASL_SUPPORT // SASL authentication handler -class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator -{ - const std::vector > getAcceptableMechanisms - (const std::vector >& available, - const vmime::shared_ptr & suggested) const - { +class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator { + + const std::vector > + getAcceptableMechanisms( + const std::vector >& available, + const vmime::shared_ptr & suggested + ) const { + std::cout << std::endl << "Available SASL mechanisms:" << std::endl; - for (unsigned int i = 0 ; i < available.size() ; ++i) - { + for (unsigned int i = 0 ; i < available.size() ; ++i) { + std::cout << " " << available[i]->getName(); - if (suggested && available[i]->getName() == suggested->getName()) + if (suggested && available[i]->getName() == suggested->getName()) { std::cout << "(suggested)"; + } } std::cout << std::endl << std::endl; @@ -24,31 +27,33 @@ class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthen return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested); } - void setSASLMechanism(const vmime::shared_ptr & mech) - { + void setSASLMechanism(const vmime::shared_ptr & mech) { + std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl; defaultSASLAuthenticator::setSASLMechanism(mech); } - const vmime::string getUsername() const - { - if (m_username.empty()) + const vmime::string getUsername() const { + + if (m_username.empty()) { m_username = getUserInput("Username"); + } return m_username; } - const vmime::string getPassword() const - { - if (m_password.empty()) + const vmime::string getPassword() const { + + if (m_password.empty()) { m_password = getUserInput("Password"); + } return m_password; } - static const vmime::string getUserInput(const std::string& prompt) - { + static const vmime::string getUserInput(const std::string& prompt) { + std::cout << prompt << ": "; std::cout.flush(); @@ -67,26 +72,28 @@ private: #else // !VMIME_HAVE_SASL_SUPPORT // Simple authentication handler -class interactiveAuthenticator : public vmime::security::defaultAuthenticator -{ - const vmime::string getUsername() const - { - if (m_username.empty()) +class interactiveAuthenticator : public vmime::security::defaultAuthenticator { + + const vmime::string getUsername() const { + + if (m_username.empty()) { m_username = getUserInput("Username"); + } return m_username; } - const vmime::string getPassword() const - { - if (m_password.empty()) + const vmime::string getPassword() const { + + if (m_password.empty()) { m_password = getUserInput("Password"); + } return m_password; } - static const vmime::string getUserInput(const std::string& prompt) - { + static const vmime::string getUserInput(const std::string& prompt) { + std::cout << prompt << ": "; std::cout.flush(); @@ -103,4 +110,3 @@ private: }; #endif // VMIME_HAVE_SASL_SUPPORT - diff --git a/examples/example6_certificateVerifier.hpp b/examples/example6_certificateVerifier.hpp index b4b47a2a..3d8bf82e 100644 --- a/examples/example6_certificateVerifier.hpp +++ b/examples/example6_certificateVerifier.hpp @@ -3,20 +3,23 @@ #if VMIME_HAVE_TLS_SUPPORT // Certificate verifier (TLS/SSL) -class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier -{ +class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier { + public: - void verify(const vmime::shared_ptr & chain, const vmime::string& hostname) - { - try - { + void verify( + const vmime::shared_ptr & chain, + const vmime::string& hostname + ) { + + try { + setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); - } - catch (vmime::security::cert::certificateException&) - { + + } catch (vmime::security::cert::certificateException&) { + // Obtain subject's certificate vmime::shared_ptr cert = chain->getAt(0); @@ -29,13 +32,14 @@ public: std::getline(std::cin, answer); if (answer.length() != 0 && - (answer[0] == 'Y' || answer[0] == 'y')) - { + (answer[0] == 'Y' || answer[0] == 'y')) { + // Accept it, and remember user's choice for later - if (cert->getType() == "X.509") - { - m_trustedCerts.push_back(vmime::dynamicCast - (cert)); + if (cert->getType() == "X.509") { + + m_trustedCerts.push_back( + vmime::dynamicCast (cert) + ); setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); @@ -44,8 +48,7 @@ public: return; } - throw vmime::security::cert::certificateException - ("User did not accept the certificate."); + throw vmime::security::cert::certificateException("User did not accept the certificate."); } } @@ -59,4 +62,3 @@ std::vector > interactiveCertificateVerifier::m_trustedCerts; #endif // VMIME_HAVE_TLS_SUPPORT - diff --git a/examples/example6_timeoutHandler.hpp b/examples/example6_timeoutHandler.hpp index 3e188baf..7999084d 100644 --- a/examples/example6_timeoutHandler.hpp +++ b/examples/example6_timeoutHandler.hpp @@ -5,17 +5,17 @@ * Used to stop the current operation after too much time, or if the user * requested cancellation. */ -class timeoutHandler : public vmime::net::timeoutHandler -{ +class timeoutHandler : public vmime::net::timeoutHandler { + public: timeoutHandler() - : m_start(time(NULL)) - { + : m_start(time(NULL)) { + } - bool isTimeOut() - { + bool isTimeOut() { + // This is a cancellation point: return true if you want to cancel // the current operation. If you return true, handleTimeOut() will // be called just after this, and before actually cancelling the @@ -25,15 +25,15 @@ public: return (time(NULL) - m_start) >= 10; // seconds } - void resetTimeOut() - { + void resetTimeOut() { + // Called at the beginning of an operation (eg. connecting, // a read() or a write() on a socket...) m_start = time(NULL); } - bool handleTimeOut() - { + bool handleTimeOut() { + // If isTimeOut() returned true, this function will be called. This // allows you to interact with the user, ie. display a prompt to // know whether he wants to cancel the operation. @@ -49,13 +49,12 @@ private: }; -class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory -{ +class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory { + public: - vmime::shared_ptr create() - { + vmime::shared_ptr create() { + return vmime::make_shared (); } }; - diff --git a/examples/example6_tracer.hpp b/examples/example6_tracer.hpp index 8f57f56c..27090cf7 100644 --- a/examples/example6_tracer.hpp +++ b/examples/example6_tracer.hpp @@ -1,25 +1,29 @@ /** Tracer used to demonstrate logging communication between client and server. */ +class myTracer : public vmime::net::tracer { -class myTracer : public vmime::net::tracer -{ public: - myTracer(const vmime::shared_ptr & stream, - const vmime::shared_ptr & serv, const int connectionId) - : m_stream(stream), m_service(serv), m_connectionId(connectionId) - { + myTracer( + const vmime::shared_ptr & stream, + const vmime::shared_ptr & serv, + const int connectionId + ) + : m_stream(stream), + m_service(serv), + m_connectionId(connectionId) { + } - void traceSend(const vmime::string& line) - { + void traceSend(const vmime::string& line) { + *m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId << "] C: " << line << std::endl; } - void traceReceive(const vmime::string& line) - { + void traceReceive(const vmime::string& line) { + *m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId << "] S: " << line << std::endl; } @@ -31,18 +35,21 @@ private: const int m_connectionId; }; -class myTracerFactory : public vmime::net::tracerFactory -{ + +class myTracerFactory : public vmime::net::tracerFactory { + public: myTracerFactory(const vmime::shared_ptr & stream) - : m_stream(stream) - { + : m_stream(stream) { + } - vmime::shared_ptr create - (const vmime::shared_ptr & serv, const int connectionId) - { + vmime::shared_ptr create( + const vmime::shared_ptr & serv, + const int connectionId + ) { + return vmime::make_shared (m_stream, serv, connectionId); } @@ -50,4 +57,3 @@ private: vmime::shared_ptr m_stream; }; - diff --git a/examples/example7.cpp b/examples/example7.cpp index ae508697..db96dbda 100644 --- a/examples/example7.cpp +++ b/examples/example7.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,16 +39,16 @@ #include "vmime/platforms/posix/posixHandler.hpp" -int main() -{ +int main() { + // Enumerate encoders vmime::shared_ptr ef = vmime::utility::encoder::encoderFactory::getInstance(); std::cout << "Available encoders:" << std::endl; - for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) - { + for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) { + vmime::shared_ptr enc = ef->getEncoderAt(i); @@ -59,8 +59,9 @@ int main() std::vector props = e->getAvailableProperties(); - for (std::vector ::const_iterator it = props.begin() ; it != props.end() ; ++it) + for (std::vector ::const_iterator it = props.begin() ; it != props.end() ; ++it) { std::cout << " - " << *it << std::endl; + } } std::cout << std::endl; @@ -71,8 +72,8 @@ int main() std::cout << "Available messaging services:" << std::endl; - for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) - { + for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) { + const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i); std::cout << " * " << serv.getName() << std::endl; @@ -81,28 +82,29 @@ int main() serv.getInfos().getAvailableProperties(); for (std::vector ::const_iterator it = props.begin() ; - it != props.end() ; ++it) - { + it != props.end() ; ++it) { + const vmime::net::serviceInfos::property& p = *it; const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName(); vmime::string type; - switch (p.getType()) - { - case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break; - case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break; - case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break; - default: type = "(unknown)"; break; + switch (p.getType()) { + case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break; + case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break; + case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break; + default: type = "(unknown)"; break; } vmime::string flags; - if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED) + if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED) { flags += " FLAG_REQUIRED"; - if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN) + } + if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN) { flags += " FLAG_HIDDEN"; + } std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName(); std::cout << " (type=" << type << ", flags=" << flags; @@ -111,5 +113,6 @@ int main() } std::cout << std::endl; -} + return 0; +} diff --git a/examples/viewer/viewer.cpp b/examples/viewer/viewer.cpp index 1d6daa05..a03120ac 100644 --- a/examples/viewer/viewer.cpp +++ b/examples/viewer/viewer.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -53,8 +53,12 @@ vmime::shared_ptr currentMessage; -void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr comp, GtkTreeIter* parent = NULL) -{ +void insertRowInModel( + GtkTreeStore* model, + vmime::shared_ptr comp, + GtkTreeIter* parent = NULL +) { + GtkTreeIter iter; gtk_tree_store_append(model, &iter, parent); @@ -62,15 +66,14 @@ void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr const std::vector > children = comp->getChildComponents(); - for (int i = 0 ; i < children.size() ; ++i) - { + for (int i = 0 ; i < children.size() ; ++i) { insertRowInModel(model, children[i], &iter); } } -void updateTreeView() -{ +void updateTreeView() { + GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView))); g_object_ref(model); @@ -85,8 +88,8 @@ void updateTreeView() } -static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) -{ +static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) { + GtkTreePath* path = NULL; GtkTreeViewColumn* col = NULL; @@ -112,19 +115,18 @@ static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) } -static void destroy(GtkWidget* widget, gpointer data) -{ +static void destroy(GtkWidget* widget, gpointer data) { + gtk_main_quit(); } -void openFile(const std::string& filename) -{ +void openFile(const std::string& filename) { + std::ifstream file; file.open(filename.c_str(), std::ios::in | std::ios::binary); - if (!file) - { + if (!file) { std::cerr << "Can't open file '" << filename << "'." << std::endl; return; } @@ -132,12 +134,10 @@ void openFile(const std::string& filename) vmime::string data; char buffer[16384]; - do - { + do { file.read(buffer, sizeof(buffer)); data += vmime::string(buffer, file.gcount()); - } - while (file.gcount()); + } while (file.gcount()); vmime::shared_ptr msg = vmime::make_shared (); msg->parse(data); @@ -147,13 +147,13 @@ void openFile(const std::string& filename) char* convData = g_convert_with_fallback(data.c_str(), data.length(), "UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL); - if (convData == NULL) - { + if (!convData) { + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), "GLib UTF-8 conversion error.", -1); - } - else - { + + } else { + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)), convData, strlen(convData)); @@ -164,16 +164,19 @@ void openFile(const std::string& filename) } -static void onFileOpen() -{ - GtkWidget* dlg = gtk_file_chooser_dialog_new - ("Open Message File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); +static void onFileOpen() { + + GtkWidget* dlg = gtk_file_chooser_dialog_new( + "Open Message File", + GTK_WINDOW(window), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + NULL + ); + + if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) { - if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) - { char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg)); openFile(filename); @@ -187,8 +190,7 @@ static void onFileOpen() // UI definitions -static const GtkActionEntry uiActions[] = -{ +static const GtkActionEntry uiActions[] = { { "FileMenu", NULL, "_File" }, { "FileOpen", GTK_STOCK_OPEN, "_Open...", "O", NULL, G_CALLBACK(onFileOpen) }, { "FileExit", GTK_STOCK_QUIT, "_Exit", "Q", NULL, G_CALLBACK(gtk_main_quit) } @@ -205,8 +207,8 @@ static const char* uiDefinition = ""; -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { + // VMime initialization vmime::platform::setHandler(); @@ -290,5 +292,3 @@ int main(int argc, char* argv[]) return 0; } - - diff --git a/src/vmime/address.cpp b/src/vmime/address.cpp index c6fa74f1..3bc434fa 100644 --- a/src/vmime/address.cpp +++ b/src/vmime/address.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,12 +29,11 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { -address::address() -{ +address::address() { + } @@ -66,10 +65,15 @@ address-list = (address *("," address)) / obs-addr-list */ -shared_ptr
address::parseNext - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition, bool *isLastAddressOfGroup) -{ +shared_ptr
address::parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + bool *isLastAddressOfGroup +) { + bool escaped = false; bool quoted = false; bool quotedRFC2047 = false; @@ -78,135 +82,151 @@ shared_ptr
address::parseNext bool stop = false; int commentLevel = 0; - if (isLastAddressOfGroup) + if (isLastAddressOfGroup) { *isLastAddressOfGroup = false; + } size_t pos = position; - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } const size_t start = pos; - while (!stop && pos < end) - { - if (escaped) - { + while (!stop && pos < end) { + + if (escaped) { + escaped = false; - } - else - { - switch (buffer[pos]) - { - case '\\': - escaped = true; - break; - case '"': - quoted = !quoted; - break; - case '<': - inRouteAddr = true; - break; - case '>': - inRouteAddr = false; - break; - case '(': + } else { - ++commentLevel; - break; + switch (buffer[pos]) { - case ')': + case '\\': - if (commentLevel > 0) - --commentLevel; + escaped = true; + break; - break; + case '"': - case '=': + quoted = !quoted; + break; - if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') - { - ++pos; - quotedRFC2047 = true; - } + case '<': - break; + inRouteAddr = true; + break; - case '?': + case '>': - if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') - { - ++pos; - quotedRFC2047 = false; - } + inRouteAddr = false; + break; - break; + case '(': - default: - { - if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) - { - switch (buffer[pos]) - { - case ';': + ++commentLevel; + break; - if (isGroup) - { - if (pos + 1 < end && buffer[pos + 1] == ',') - ++pos; - } + case ')': - if (isLastAddressOfGroup) - *isLastAddressOfGroup = true; - - stop = true; - break; - - case ':': - - isGroup = true; - break; - - case ',': - - if (!isGroup) stop = true; - break; + if (commentLevel > 0) { + --commentLevel; } - } - break; - } + break; + + case '=': + + if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') { + ++pos; + quotedRFC2047 = true; + } + + break; + + case '?': + + if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') { + ++pos; + quotedRFC2047 = false; + } + + break; + + default: + { + if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) { + + switch (buffer[pos]) { + + case ';': + + if (isGroup) { + + if (pos + 1 < end && buffer[pos + 1] == ',') { + ++pos; + } + } + + if (isLastAddressOfGroup) { + *isLastAddressOfGroup = true; + } + + stop = true; + break; + + case ':': + + isGroup = true; + break; + + case ',': + + if (!isGroup) { + stop = true; + } + + break; + } + } + + break; + } } } - if (!stop) + if (!stop) { ++pos; + } } - if (newPosition) - { - if (pos == end) + if (newPosition) { + + if (pos == end) { *newPosition = end; - else + } else { *newPosition = pos + 1; // ',' or ';' + } } // Parse extracted address (mailbox or group) - if (pos != start) - { + if (pos != start) { + shared_ptr
parsedAddress; - if (isGroup) + if (isGroup) { parsedAddress = make_shared (); - else + } else { parsedAddress = make_shared (); + } parsedAddress->parse(ctx, buffer, start, pos, NULL); parsedAddress->setParsedBounds(start, pos); - return (parsedAddress); + return parsedAddress; } return null; diff --git a/src/vmime/address.hpp b/src/vmime/address.hpp index 5eb510f9..f83f2381 100644 --- a/src/vmime/address.hpp +++ b/src/vmime/address.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,7 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** Abstract class representing a mailbox or a group of mailboxes. @@ -38,9 +37,8 @@ namespace vmime * This class define a common behaviour for the mailbox * and mailboxGroup classes. */ +class VMIME_EXPORT address : public headerFieldValue { -class VMIME_EXPORT address : public headerFieldValue -{ protected: address(); @@ -74,10 +72,14 @@ public: * 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 shared_ptr
parseNext - (const parsingContext& ctx, const string& buffer, - const size_t position, const size_t end, - size_t* newPosition, bool *isLastAddressOfGroup); + static shared_ptr
parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + bool *isLastAddressOfGroup + ); }; diff --git a/src/vmime/addressList.cpp b/src/vmime/addressList.cpp index 23834f6f..03c9e8f4 100644 --- a/src/vmime/addressList.cpp +++ b/src/vmime/addressList.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,181 +28,204 @@ #include "vmime/mailboxGroup.hpp" -namespace vmime -{ +namespace vmime { -addressList::addressList() -{ +addressList::addressList() { + } addressList::addressList(const addressList& addrList) - : headerFieldValue() -{ + : headerFieldValue() { + copyFrom(addrList); } -addressList::~addressList() -{ +addressList::~addressList() { + removeAllAddresses(); } -void addressList::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void addressList::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + removeAllAddresses(); size_t pos = position; - while (pos < end) - { + while (pos < end) { + shared_ptr
parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL); - if (parsedAddress != NULL) + if (parsedAddress) { m_list.push_back(parsedAddress); + } } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void addressList::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void addressList::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + size_t pos = curLinePos; generationContext tmpCtx(ctx); tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2); - if (!m_list.empty()) - { - for (std::vector >::const_iterator i = m_list.begin() ; ; ) - { + if (!m_list.empty()) { + + for (std::vector >::const_iterator i = m_list.begin() ; ; ) { + (*i)->generate(ctx, os, pos, &pos); - if (++i == m_list.end()) + if (++i == m_list.end()) { break; + } os << ", "; pos += 2; } } - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } -void addressList::copyFrom(const component& other) -{ +void addressList::copyFrom(const component& other) { + const addressList& addrList = dynamic_cast (other); removeAllAddresses(); for (std::vector >::const_iterator it = addrList.m_list.begin() ; - it != addrList.m_list.end() ; ++it) - { + it != addrList.m_list.end() ; ++it) { + m_list.push_back(vmime::clone(*it)); } } -addressList& addressList::operator=(const addressList& other) -{ +addressList& addressList::operator=(const addressList& other) { + copyFrom(other); - return (*this); + return *this; } -addressList& addressList::operator=(const mailboxList& other) -{ +addressList& addressList::operator=(const mailboxList& other) { + removeAllAddresses(); - for (size_t i = 0 ; i < other.getMailboxCount() ; ++i) + for (size_t i = 0 ; i < other.getMailboxCount() ; ++i) { m_list.push_back(dynamicCast
(other.getMailboxAt(i)->clone())); + } - return (*this); + return *this; } -shared_ptr addressList::clone() const -{ +shared_ptr addressList::clone() const { + return make_shared (*this); } -void addressList::appendAddress(const shared_ptr
&addr) -{ +void addressList::appendAddress(const shared_ptr
&addr) { + m_list.push_back(addr); } -void addressList::insertAddressBefore(const shared_ptr
& beforeAddress, const shared_ptr
& addr) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), beforeAddress); +void addressList::insertAddressBefore(const shared_ptr
& beforeAddress, const shared_ptr
& addr) { - if (it == m_list.end()) + const std::vector >::iterator it = std::find( + m_list.begin(), m_list.end(), beforeAddress + ); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.insert(it, addr); } -void addressList::insertAddressBefore(const size_t pos, const shared_ptr
& addr) -{ - if (pos >= m_list.size()) +void addressList::insertAddressBefore(const size_t pos, const shared_ptr
& addr) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } m_list.insert(m_list.begin() + pos, addr); } -void addressList::insertAddressAfter(const shared_ptr
& afterAddress, const shared_ptr
& addr) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), afterAddress); +void addressList::insertAddressAfter( + const shared_ptr
& afterAddress, + const shared_ptr
& addr +) { - if (it == m_list.end()) + const std::vector >::iterator it = std::find( + m_list.begin(), m_list.end(), afterAddress + ); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.insert(it + 1, addr); } -void addressList::insertAddressAfter(const size_t pos, const shared_ptr
& addr) -{ - if (pos >= m_list.size()) +void addressList::insertAddressAfter(const size_t pos, const shared_ptr
& addr) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } m_list.insert(m_list.begin() + pos + 1, addr); } -void addressList::removeAddress(const shared_ptr
& addr) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), addr); +void addressList::removeAddress(const shared_ptr
& addr) { - if (it == m_list.end()) + const std::vector >::iterator it = std::find( + m_list.begin(), m_list.end(), addr + ); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.erase(it); } -void addressList::removeAddress(const size_t pos) -{ - if (pos >= m_list.size()) +void addressList::removeAddress(const size_t pos) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } const std::vector >::iterator it = m_list.begin() + pos; @@ -210,90 +233,90 @@ void addressList::removeAddress(const size_t pos) } -void addressList::removeAllAddresses() -{ +void addressList::removeAllAddresses() { + m_list.clear(); } -size_t addressList::getAddressCount() const -{ - return (m_list.size()); +size_t addressList::getAddressCount() const { + + return m_list.size(); } -bool addressList::isEmpty() const -{ - return (m_list.empty()); +bool addressList::isEmpty() const { + + return m_list.empty(); } -shared_ptr
addressList::getAddressAt(const size_t pos) -{ - return (m_list[pos]); +shared_ptr
addressList::getAddressAt(const size_t pos) { + + return m_list[pos]; } -const shared_ptr addressList::getAddressAt(const size_t pos) const -{ - return (m_list[pos]); +const shared_ptr addressList::getAddressAt(const size_t pos) const { + + return m_list[pos]; } -const std::vector > addressList::getAddressList() const -{ +const std::vector > addressList::getAddressList() const { + std::vector > list; list.reserve(m_list.size()); for (std::vector >::const_iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { + it != m_list.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > addressList::getAddressList() -{ - return (m_list); +const std::vector > addressList::getAddressList() { + + return m_list; } -const std::vector > addressList::getChildComponents() -{ +const std::vector > addressList::getChildComponents() { + std::vector > list; copy_vector(m_list, list); - return (list); + return list; } -shared_ptr addressList::toMailboxList() const -{ +shared_ptr addressList::toMailboxList() const { + shared_ptr res = make_shared (); for (std::vector >::const_iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { + it != m_list.end() ; ++it) { + shared_ptr addr = *it; - if (addr->isGroup()) - { + if (addr->isGroup()) { + const std::vector > mailboxes = dynamicCast (addr)->getMailboxList(); for (std::vector >::const_iterator jt = mailboxes.begin() ; - jt != mailboxes.end() ; ++jt) - { + jt != mailboxes.end() ; ++jt) { + res->appendMailbox(vmime::clone(*jt)); } - } - else - { + + } else { + res->appendMailbox(dynamicCast (addr->clone())); } } diff --git a/src/vmime/addressList.hpp b/src/vmime/addressList.hpp index c0909069..69cbd74a 100644 --- a/src/vmime/addressList.hpp +++ b/src/vmime/addressList.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,8 +31,7 @@ #include "vmime/address.hpp" -namespace vmime -{ +namespace vmime { class mailboxList; @@ -40,9 +39,8 @@ class mailboxList; /** A list of addresses. */ +class VMIME_EXPORT addressList : public headerFieldValue { -class VMIME_EXPORT addressList : public headerFieldValue -{ public: addressList(); @@ -71,7 +69,10 @@ public: * @param addr address to insert * @throw std::out_of_range if the address is not in the list */ - void insertAddressBefore(const shared_ptr
& beforeAddress, const shared_ptr
& addr); + void insertAddressBefore( + const shared_ptr
& beforeAddress, + const shared_ptr
& addr + ); /** Insert a new address before the specified position. * @@ -88,7 +89,10 @@ public: * @param addr address to insert * @throw std::out_of_range if the address is not in the list */ - void insertAddressAfter(const shared_ptr
& afterAddress, const shared_ptr
& addr); + void insertAddressAfter( + const shared_ptr
& afterAddress, + const shared_ptr
& addr + ); /** Insert a new address after the specified position. * @@ -171,18 +175,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/attachment.hpp b/src/vmime/attachment.hpp index 862e5d9e..be20e33d 100644 --- a/src/vmime/attachment.hpp +++ b/src/vmime/attachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,15 +34,13 @@ #include "vmime/encoding.hpp" -namespace vmime -{ +namespace vmime { /** Base class for all types of attachment. */ +class VMIME_EXPORT attachment : public object { -class VMIME_EXPORT attachment : public object -{ friend class messageBuilder; friend class messageParser; friend class attachmentHelper; diff --git a/src/vmime/attachmentHelper.cpp b/src/vmime/attachmentHelper.cpp index 252a0377..86051226 100644 --- a/src/vmime/attachmentHelper.cpp +++ b/src/vmime/attachmentHelper.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,36 +33,39 @@ #include -namespace vmime -{ +namespace vmime { // static -bool attachmentHelper::isBodyPartAnAttachment - (const shared_ptr & part, const unsigned int options) -{ +bool attachmentHelper::isBodyPartAnAttachment( + const shared_ptr & part, + const unsigned int options +) { + // First, try with "Content-Disposition" field. // If not present, we will try with "Content-Type" field. shared_ptr cdf = part->getHeader()->findField (fields::CONTENT_DISPOSITION); - if (cdf) - { + if (cdf) { + const contentDisposition disp = *cdf->getValue (); - if (disp.getName() != contentDispositionTypes::INLINE) + if (disp.getName() != contentDispositionTypes::INLINE) { return true; + } + + if ((options & INLINE_OBJECTS) == 0) { - if ((options & INLINE_OBJECTS) == 0) - { // If the Content-Disposition is 'inline' and there is no // Content-Id or Content-Location field, it may be an attachment if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) && - !part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION)) - { + !part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION)) { + // If this is the root part, it might not be an attachment - if (part->getParentPart() == NULL) + if (!part->getParentPart()) { return false; + } return true; } @@ -78,40 +81,46 @@ bool attachmentHelper::isBodyPartAnAttachment shared_ptr ctf = part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + type = *ctf->getValue (); - if (ctf->hasParameter("name")) + if (ctf->hasParameter("name")) { hasContentTypeName = true; - } - else - { + } + + } else { + // If this is the root part and no Content-Type field is present, // then this may not be a MIME message, so do not assume it is // an attachment - if (part->getParentPart() == NULL) + if (!part->getParentPart()) { return false; + } // No "Content-type" field: assume "application/octet-stream". - type = mediaType(mediaTypes::APPLICATION, - mediaTypes::APPLICATION_OCTET_STREAM); + type = mediaType( + mediaTypes::APPLICATION, + mediaTypes::APPLICATION_OCTET_STREAM + ); } if (type.getType() != mediaTypes::TEXT && - type.getType() != mediaTypes::MULTIPART) - { + type.getType() != mediaTypes::MULTIPART) { + // Compatibility with (obsolete) RFC-1341: if there is a "name" parameter // on the "Content-Type" field, then we assume it is an attachment - if (hasContentTypeName) + if (hasContentTypeName) { return true; + } + + if ((options & INLINE_OBJECTS) == 0) { - if ((options & INLINE_OBJECTS) == 0) - { // If a "Content-Id" field is present, it might be an // embedded object (MHTML messages) - if (part->getHeader()->hasField(vmime::fields::CONTENT_ID)) + if (part->getHeader()->hasField(vmime::fields::CONTENT_ID)) { return false; + } } return true; @@ -122,35 +131,40 @@ bool attachmentHelper::isBodyPartAnAttachment // static -shared_ptr attachmentHelper::getBodyPartAttachment - (const shared_ptr & part, const unsigned int options) -{ - if (!isBodyPartAnAttachment(part, options)) +shared_ptr attachmentHelper::getBodyPartAttachment( + const shared_ptr & part, + const unsigned int options +) { + + if (!isBodyPartAnAttachment(part, options)) { return null; + } mediaType type; shared_ptr ctf = part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + type = *ctf->getValue (); - } - else - { + + } else { + // No "Content-type" field: assume "application/octet-stream". - type = mediaType(mediaTypes::APPLICATION, - mediaTypes::APPLICATION_OCTET_STREAM); + type = mediaType( + mediaTypes::APPLICATION, + mediaTypes::APPLICATION_OCTET_STREAM + ); } if (type.getType() == mediaTypes::MESSAGE && - type.getSubType() == mediaTypes::MESSAGE_RFC822) - { + type.getSubType() == mediaTypes::MESSAGE_RFC822) { + return make_shared (part); - } - else - { + + } else { + return make_shared (part); } } @@ -158,32 +172,36 @@ shared_ptr attachmentHelper::getBodyPartAttachment // static const std::vector > - attachmentHelper::findAttachmentsInMessage - (const shared_ptr & msg, const unsigned int options) -{ + attachmentHelper::findAttachmentsInMessage( + const shared_ptr & msg, + const unsigned int options + ) { + return findAttachmentsInBodyPart(msg, options); } // static const std::vector > - attachmentHelper::findAttachmentsInBodyPart - (const shared_ptr & part, const unsigned int options) -{ + attachmentHelper::findAttachmentsInBodyPart( + const shared_ptr & part, + const unsigned int options + ) { + std::vector > atts; // Test this part - if (isBodyPartAnAttachment(part, options)) - { + if (isBodyPartAnAttachment(part, options)) { + atts.push_back(getBodyPartAttachment(part, options)); - } + // Find in sub-parts - else - { + } else { + shared_ptr bdy = part->getBody(); - for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) - { + for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) { + std::vector > partAtts = findAttachmentsInBodyPart(bdy->getPartAt(i), options); @@ -196,35 +214,39 @@ const std::vector > // static -void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & att) -{ +void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & att) { + // We simply search for a "multipart/mixed" part. If no one exists, // create it in the root part. This (very simple) algorithm should // work in the most cases. - vmime::mediaType mpMixed(vmime::mediaTypes::MULTIPART, - vmime::mediaTypes::MULTIPART_MIXED); + vmime::mediaType mpMixed( + vmime::mediaTypes::MULTIPART, + vmime::mediaTypes::MULTIPART_MIXED + ); shared_ptr part = findBodyPart(msg, mpMixed); - if (part == NULL) // create it - { - if (msg->getBody()->getPartCount() != 0) - { + if (!part) { // create it + + if (msg->getBody()->getPartCount() != 0) { + // Create a new container part for the parts that were in // the root part of the message shared_ptr container = make_shared (); - if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) - { - container->getHeader()->ContentType()->setValue - (msg->getHeader()->ContentType()->getValue()); + if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) { + + container->getHeader()->ContentType()->setValue( + msg->getHeader()->ContentType()->getValue() + ); } - if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) - { - container->getHeader()->ContentTransferEncoding()->setValue - (msg->getHeader()->ContentTransferEncoding()->getValue()); + if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) { + + container->getHeader()->ContentTransferEncoding()->setValue( + msg->getHeader()->ContentTransferEncoding()->getValue() + ); } // Move parts from the root part to this new part @@ -233,28 +255,31 @@ void attachmentHelper::addAttachment(const shared_ptr & msg, const shar msg->getBody()->removeAllParts(); - for (unsigned int i = 0 ; i < partList.size() ; ++i) + for (unsigned int i = 0 ; i < partList.size() ; ++i) { container->getBody()->appendPart(partList[i]); + } msg->getBody()->appendPart(container); - } - else - { + + } else { + // The message is a simple (RFC-822) message, and do not // contains any MIME part. Move the contents from the // root to a new child part. shared_ptr child = make_shared (); - if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) - { - child->getHeader()->ContentType()->setValue - (msg->getHeader()->ContentType()->getValue()); + if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) { + + child->getHeader()->ContentType()->setValue( + msg->getHeader()->ContentType()->getValue() + ); } - if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) - { - child->getHeader()->ContentTransferEncoding()->setValue - (msg->getHeader()->ContentTransferEncoding()->getValue()); + if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) { + + child->getHeader()->ContentTransferEncoding()->setValue( + msg->getHeader()->ContentTransferEncoding()->getValue() + ); } child->getBody()->setContents(msg->getBody()->getContents()); @@ -278,22 +303,25 @@ void attachmentHelper::addAttachment(const shared_ptr & msg, const shar // static -shared_ptr attachmentHelper::findBodyPart - (const shared_ptr & part, const mediaType& type) -{ - if (part->getBody()->getContentType() == type) +shared_ptr attachmentHelper::findBodyPart( + const shared_ptr & part, + const mediaType& type +) { + + if (part->getBody()->getContentType() == type) { return part; + } // Try in sub-parts shared_ptr bdy = part->getBody(); - for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) - { - shared_ptr found = - findBodyPart(bdy->getPartAt(i), type); + for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) { - if (found != NULL) + shared_ptr found = findBodyPart(bdy->getPartAt(i), type); + + if (found) { return found; + } } return null; @@ -301,12 +329,11 @@ shared_ptr attachmentHelper::findBodyPart // static -void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & amsg) -{ +void attachmentHelper::addAttachment(const shared_ptr & msg, const shared_ptr & amsg) { + shared_ptr att = make_shared (amsg); addAttachment(msg, att); } } // vmime - diff --git a/src/vmime/attachmentHelper.hpp b/src/vmime/attachmentHelper.hpp index f1588fe8..f28819fb 100644 --- a/src/vmime/attachmentHelper.hpp +++ b/src/vmime/attachmentHelper.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,14 +31,13 @@ #include "vmime/message.hpp" -namespace vmime -{ +namespace vmime { /** Retrieve attachment information from message parts. */ -class VMIME_EXPORT attachmentHelper -{ +class VMIME_EXPORT attachmentHelper { + public: /** Options for use with the following functions: @@ -46,8 +45,7 @@ public: * getBodyPartAttachment, * and isBodyPartAnAttachment. */ - enum FindOptions - { + enum FindOptions { INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to consider MHTML objects (parts with a "Content-Id" or a "Content-Location", such as inline images) as attachments. */ @@ -59,7 +57,10 @@ public: * @param options search options (see FindOptions) * @return true if the part is an attachment, false otherwise */ - static bool isBodyPartAnAttachment(const shared_ptr & part, const unsigned int options = 0); + static bool isBodyPartAnAttachment( + const shared_ptr & part, + const unsigned int options = 0 + ); /** Return attachment information in the specified body part. * If the specified body part does not contain attachment @@ -69,8 +70,10 @@ public: * @param options search options (see FindOptions) * @return attachment found in the part, or NULL */ - static shared_ptr - getBodyPartAttachment(const shared_ptr & part, const unsigned int options = 0); + static shared_ptr getBodyPartAttachment( + const shared_ptr & part, + const unsigned int options = 0 + ); /** Find all attachments contained in the specified part * and all its children parts. @@ -81,7 +84,10 @@ public: * @return a list of attachments found */ static const std::vector > - findAttachmentsInBodyPart(const shared_ptr & part, const unsigned int options = 0); + findAttachmentsInBodyPart( + const shared_ptr & part, + const unsigned int options = 0 + ); /** Find all attachments contained in the specified message. * This is simply a recursive call to getBodyPartAttachment(). @@ -91,26 +97,37 @@ public: * @return a list of attachments found */ static const std::vector > - findAttachmentsInMessage(const shared_ptr & msg, const unsigned int options = 0); + findAttachmentsInMessage( + const shared_ptr & msg, + const unsigned int options = 0 + ); /** Add an attachment to the specified message. * * @param msg message into which to add the attachment * @param att attachment to add */ - static void addAttachment(const shared_ptr & msg, const shared_ptr & att); + static void addAttachment( + const shared_ptr & msg, + const shared_ptr & att + ); /** Add a message attachment to the specified message. * * @param msg message into which to add the attachment * @param amsg message to attach */ - static void addAttachment(const shared_ptr & msg, const shared_ptr & amsg); + static void addAttachment( + const shared_ptr & msg, + const shared_ptr & amsg + ); protected: - static shared_ptr findBodyPart - (const shared_ptr & part, const mediaType& type); + static shared_ptr findBodyPart( + const shared_ptr & part, + const mediaType& type + ); }; @@ -118,4 +135,3 @@ protected: #endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED - diff --git a/src/vmime/base.cpp b/src/vmime/base.cpp index 9f9a87be..395d7b32 100644 --- a/src/vmime/base.cpp +++ b/src/vmime/base.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -48,8 +48,7 @@ #endif -namespace vmime -{ +namespace vmime { /** "Null" (empty) string. @@ -108,8 +107,8 @@ nullPtrType null; // Line length limits -namespace lineLengthLimits -{ +namespace lineLengthLimits { + const size_t infinite = std::numeric_limits ::max(); } @@ -134,12 +133,10 @@ const size_t npos = std::numeric_limits ::max(); // constructor, for example). // -class initializer -{ -public: +struct initializer { + + initializer() { - initializer() - { parsingContext::getDefaultContext(); generationContext::getDefaultContext(); diff --git a/src/vmime/base.hpp b/src/vmime/base.hpp index b39ff55e..77824771 100644 --- a/src/vmime/base.hpp +++ b/src/vmime/base.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,8 @@ #include "vmime/constants.hpp" -namespace vmime -{ +namespace vmime { + class text; class word; class charset; @@ -53,9 +53,9 @@ namespace vmime #ifndef VMIME_BUILDING_DOC // Null pointer - struct nullPtrType - { - template + struct nullPtrType { + + template operator shared_ptr () { return shared_ptr (); } }; @@ -78,47 +78,48 @@ namespace vmime // template - inline T const* cbegin(T const (&array)[N]) - { - return (array); + inline T const* cbegin(T const (&array)[N]) { + + return array; } template - inline T const* cend(T const (&array)[N]) - { - return (array + N); + inline T const* cend(T const (&array)[N]) { + + return array + N; } template - inline T* begin(T (&array)[N]) - { - return (array); + inline T* begin(T (&array)[N]) { + + return array; } template - inline T* end(T (&array)[N]) - { - return (array + N); + inline T* end(T (&array)[N]) { + + return array + N; } template - inline size_t count(T const (&/* array */)[N]) - { - return (N); + inline size_t count(T const (&/* array */)[N]) { + + return N; } // Copy one vector to another, with type conversion template - void copy_vector(const T1& v1, T2& v2) - { + void copy_vector(const T1& v1, T2& v2) { + const typename T1::size_type count = v1.size(); v2.resize(count); - for (typename T1::size_type i = 0 ; i < count ; ++i) + for (typename T1::size_type i = 0 ; i < count ; ++i) { v2[i] = v1[i]; + } } @@ -154,12 +155,11 @@ namespace vmime character limit) for the sake of robustness. */ - namespace lineLengthLimits - { + namespace lineLengthLimits { + extern VMIME_EXPORT const size_t infinite; - enum - { + enum { max = 998, convenient = 78 }; @@ -192,8 +192,8 @@ namespace vmime * This is an alias for dynamic_pointer_cast (obj->clone()). */ template - shared_ptr clone(const shared_ptr & obj) - { + shared_ptr clone(const shared_ptr & obj) { + return dynamic_pointer_cast (obj->clone()); } @@ -201,8 +201,8 @@ namespace vmime * This is an alias for dynamic_pointer_cast (obj->clone()). */ template - shared_ptr clone(const shared_ptr & obj) - { + shared_ptr clone(const shared_ptr & obj) { + return dynamic_pointer_cast (obj->clone()); } @@ -210,8 +210,8 @@ namespace vmime * This is an alias for dynamic_pointer_cast (obj.clone()). */ template - shared_ptr clone(const T& obj) - { + shared_ptr clone(const T& obj) { + return dynamic_pointer_cast (obj.clone()); } @@ -220,24 +220,24 @@ namespace vmime * type Type, and DerivedType is derived from Type. */ template - shared_ptr dynamicCast(const shared_ptr & obj) - { + shared_ptr dynamicCast(const shared_ptr & obj) { + return dynamic_pointer_cast (obj); } /** Const cast helper. */ template - shared_ptr constCast(const shared_ptr & obj) - { + shared_ptr constCast(const shared_ptr & obj) { + return const_pointer_cast (obj); } /** Inherit from this class to indicate the subclass is not copyable, * ie. you want to prohibit copy construction and copy assignment. */ - class VMIME_EXPORT noncopyable - { + class VMIME_EXPORT noncopyable { + protected: noncopyable() { } diff --git a/src/vmime/body.cpp b/src/vmime/body.cpp index 41624b7b..3757026d 100644 --- a/src/vmime/body.cpp +++ b/src/vmime/body.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,75 +39,81 @@ #include "vmime/streamContentHandler.hpp" -namespace vmime -{ +namespace vmime { body::body() - : m_contents(make_shared ()) -{ + : m_contents(make_shared ()) { + } -body::~body() -{ +body::~body() { + } // static -size_t body::findNextBoundaryPosition - (const shared_ptr & parser, const string& boundary, - const size_t position, const size_t end, - size_t* boundaryStart, size_t* boundaryEnd) -{ +size_t body::findNextBoundaryPosition( + const shared_ptr & parser, + const string& boundary, + const size_t position, + const size_t end, + size_t* boundaryStart, + size_t* boundaryEnd +) { + size_t pos = position; - while (pos != npos && pos < end) - { + while (pos != npos && pos < end) { + pos = parser->findNext(boundary, pos); - if (pos == npos) + if (pos == npos) { break; // not found + } + + if (pos != 0) { - if (pos != 0) - { // Skip transport padding bytes (SPACE or HTAB), if any size_t advance = 0; - while (pos != 0) - { + while (pos != 0) { + parser->seek(pos - advance - 1); const byte_t c = parser->peekByte(); - if (c == ' ' || c == '\t') + if (c == ' ' || c == '\t') { ++advance; - else + } else { break; + } } // Ensure the bytes before boundary are "[LF]--": boundary should be // at the beginning of a line, and should start with "--" - if (pos - advance >= 3) - { + if (pos - advance >= 3) { + parser->seek(pos - advance - 3); - if (parser->matchBytes("\n--", 3)) - { + if (parser->matchBytes("\n--", 3)) { + parser->seek(pos + boundary.length()); const byte_t next = parser->peekByte(); // Boundary should be followed by a new line or a dash - if (next == '\r' || next == '\n' || next == '-') - { + if (next == '\r' || next == '\n' || next == '-') { + // Get rid of the "[CR]" just before "[LF]--", if any - if (pos - advance >= 4) - { + if (pos - advance >= 4) { + parser->seek(pos - advance - 4); - if (parser->peekByte() == '\r') + if (parser->peekByte() == '\r') { advance++; + } } *boundaryStart = pos - advance - 3; @@ -127,23 +133,26 @@ size_t body::findNextBoundaryPosition } -void body::parseImpl - (const parsingContext& ctx, - const shared_ptr & parser, - const size_t position, const size_t end, size_t* newPosition) -{ +void body::parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition +) { + removeAllParts(); m_prologText.clear(); m_epilogText.clear(); - if (end == position) - { + if (end == position) { setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } return; } @@ -156,40 +165,41 @@ void body::parseImpl shared_ptr ctf = m_part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + const mediaType type = *ctf->getValue (); - if (type.getType() == mediaTypes::MULTIPART) - { + if (type.getType() == mediaTypes::MULTIPART) { + isMultipart = true; - if (ctf->hasBoundary()) - { + if (ctf->hasBoundary()) { + boundary = ctf->getBoundary(); - } - else - { + + } else { + // No "boundary" parameter specified: we can try to // guess it by scanning the body contents... size_t pos = position; parser->seek(pos); - if (pos + 2 < end && parser->matchBytes("--", 2)) - { + if (pos + 2 < end && parser->matchBytes("--", 2)) { + pos += 2; - } - else - { + + } else { + pos = parser->findNext("\n--", position); - if ((pos != npos) && (pos + 3 < end)) + if ((pos != npos) && (pos + 3 < end)) { pos += 3; // skip \n-- + } } - if ((pos != npos) && (pos < end)) - { + if ((pos != npos) && (pos < end)) { + parser->seek(pos); // Read some bytes after boundary separator @@ -202,8 +212,9 @@ void body::parseImpl // Skip transport padding bytes (SPACE or HTAB), if any size_t boundarySkip = 0; - while (boundarySkip < bufferLen && parserHelpers::isSpace(buffer[boundarySkip])) + while (boundarySkip < bufferLen && parserHelpers::isSpace(buffer[boundarySkip])) { ++boundarySkip; + } // Extract boundary from buffer (stop at first CR or LF). // We have to stop after a reasonnably long boundary length (100) @@ -213,26 +224,27 @@ void body::parseImpl for (byte_t c = buffer[boundarySkip] ; boundaryLen < bufferLen && boundaryLen < 100 && !(c == '\r' || c == '\n') ; - ++boundaryLen, c = buffer[boundarySkip + boundaryLen]) - { + ++boundaryLen, c = buffer[boundarySkip + boundaryLen]) { + boundaryBytes[boundaryLen] = c; } - if (boundaryLen >= 1 && boundaryLen < 100) - { + if (boundaryLen >= 1 && boundaryLen < 100) { + // RFC #1521, Page 31: // "...the boundary parameter, which consists of 1 to 70 // characters from a set of characters known to be very // robust through email gateways, and NOT ending with // white space..." while (boundaryLen != 0 && - parserHelpers::isSpace(boundaryBytes[boundaryLen - 1])) - { + parserHelpers::isSpace(boundaryBytes[boundaryLen - 1])) { + boundaryLen--; } - if (boundaryLen >= 1) + if (boundaryLen >= 1) { boundary = string(boundaryBytes, boundaryBytes + boundaryLen); + } } } } @@ -240,8 +252,8 @@ void body::parseImpl } // This is a multi-part body - if (isMultipart && !boundary.empty()) - { + if (isMultipart && !boundary.empty()) { + size_t partStart = position; size_t pos = position; @@ -251,15 +263,15 @@ void body::parseImpl size_t boundaryStart, boundaryEnd; pos = findNextBoundaryPosition(parser, boundary, pos, end, &boundaryStart, &boundaryEnd); - for (int index = 0 ; !lastPart && (pos != npos) && (pos < end) ; ++index) - { + for (int index = 0 ; !lastPart && (pos != npos) && (pos < end) ; ++index) { + size_t partEnd = boundaryStart; // Check whether it is the last part (boundary terminated by "--") parser->seek(boundaryEnd); - if (boundaryEnd + 1 < end && parser->matchBytes("--", 2)) - { + if (boundaryEnd + 1 < end && parser->matchBytes("--", 2)) { + lastPart = true; boundaryEnd += 2; } @@ -272,37 +284,35 @@ void body::parseImpl boundaryEnd += parser->skipIf(parserHelpers::isSpaceOrTab, end); // End of boundary line - if (boundaryEnd + 1 < end && parser->matchBytes("\r\n", 2)) - { + if (boundaryEnd + 1 < end && parser->matchBytes("\r\n", 2)) { boundaryEnd += 2; - } - else if (boundaryEnd < end && parser->peekByte() == '\n') - { + } else if (boundaryEnd < end && parser->peekByte() == '\n') { ++boundaryEnd; } - if (index == 0) - { - if (partEnd > partStart) - { + if (index == 0) { + + if (partEnd > partStart) { + vmime::text text; text.parse(ctx, parser, partStart, partEnd); m_prologText = text.getWholeBuffer(); - } - else - { + + } else { + m_prologText = ""; } - } - else // index > 0 - { + + } else { // index > 0 + shared_ptr part = m_part->createChildPart(); // End before start may happen on empty bodyparts (directly // successive boundaries without even a line-break) - if (partEnd < partStart) + if (partEnd < partStart) { std::swap(partStart, partEnd); + } part->parse(ctx, parser, partStart, partEnd, NULL); @@ -312,51 +322,49 @@ void body::parseImpl partStart = boundaryEnd; // Find the next boundary - pos = findNextBoundaryPosition - (parser, boundary, boundaryEnd, end, &boundaryStart, &boundaryEnd); + pos = findNextBoundaryPosition( + parser, boundary, boundaryEnd, end, &boundaryStart, &boundaryEnd + ); } m_contents = make_shared (); // Last part was not found: recover from missing boundary - if (!lastPart && pos == npos) - { + if (!lastPart && pos == npos) { + shared_ptr part = m_part->createChildPart(); - try - { + try { part->parse(ctx, parser, partStart, end); - } - catch (std::exception&) - { + } catch (std::exception&) { throw; } m_parts.push_back(part); - } + // Treat remaining text as epilog - else if (partStart < end) - { + } else if (partStart < end) { + vmime::text text; text.parse(ctx, parser, partStart, end); m_epilogText = text.getWholeBuffer(); } - } + // Treat the contents as 'simple' data - else - { + } else { + encoding enc; shared_ptr cef = m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING); - if (cef) - { + if (cef) { + enc = *cef->getValue (); - } - else - { + + } else { + // Defaults to "7bit" (RFC-1521) enc = vmime::encoding(encodingTypes::SEVEN_BIT); } @@ -365,21 +373,23 @@ void body::parseImpl const size_t length = end - position; shared_ptr contentStream = - make_shared - (parser->getUnderlyingStream(), position, length); + make_shared ( + parser->getUnderlyingStream(), position, length + ); m_contents = make_shared (contentStream, length, enc); } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -text body::getActualPrologText(const generationContext& ctx) const -{ +text body::getActualPrologText(const generationContext& ctx) const { + const string& prologText = m_prologText.empty() ? (isRootPart() @@ -388,15 +398,16 @@ text body::getActualPrologText(const generationContext& ctx) const ) : m_prologText; - if (prologText.empty()) + if (prologText.empty()) { return text(); - else + } else { return text(prologText, vmime::charset("us-ascii")); + } } -text body::getActualEpilogText(const generationContext& ctx) const -{ +text body::getActualEpilogText(const generationContext& ctx) const { + const string& epilogText = m_epilogText.empty() ? (isRootPart() @@ -405,47 +416,51 @@ text body::getActualEpilogText(const generationContext& ctx) const ) : m_epilogText; - if (epilogText.empty()) + if (epilogText.empty()) { return text(); - else + } else { return text(epilogText, vmime::charset("us-ascii")); + } } -void body::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t /* curLinePos */, size_t* newLinePos) const -{ +void body::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t /* curLinePos */, + size_t* newLinePos +) const { + // MIME-Multipart - if (getPartCount() != 0) - { + if (getPartCount() != 0) { + string boundary; - if (!m_part) - { + if (!m_part) { + boundary = generateRandomBoundaryString(); - } - else - { + + } else { + // Use current boundary string, if specified. If no "Content-Type" field is // present, or the boundary is not specified, generate a random one shared_ptr ctf = m_part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { - if (ctf->hasBoundary()) - { + if (ctf) { + + if (ctf->hasBoundary()) { + boundary = ctf->getBoundary(); - } - else - { + + } else { + // No boundary string specified boundary = generateRandomBoundaryString(); } - } - else - { + + } else { + // No Content-Type (and no boundary string specified) boundary = generateRandomBoundaryString(); } @@ -454,18 +469,20 @@ void body::generateImpl const text prologText = getActualPrologText(ctx); const text epilogText = getActualEpilogText(ctx); - if (!prologText.isEmpty()) - { - prologText.encodeAndFold(ctx, os, 0, - NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); + if (!prologText.isEmpty()) { + + prologText.encodeAndFold( + ctx, os, 0, NULL, + text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE + ); os << CRLF; } os << "--" << boundary; - for (size_t p = 0 ; p < getPartCount() ; ++p) - { + for (size_t p = 0 ; p < getPartCount() ; ++p) { + os << CRLF; getPartAt(p)->generate(ctx, os, 0); @@ -475,20 +492,23 @@ void body::generateImpl os << "--" << CRLF; - if (!epilogText.isEmpty()) - { - epilogText.encodeAndFold(ctx, os, 0, - NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); + if (!epilogText.isEmpty()) { + + epilogText.encodeAndFold( + ctx, os, 0, NULL, + text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE + ); os << CRLF; } - if (newLinePos) + if (newLinePos) { *newLinePos = 0; - } + } + // Simple body - else - { + } else { + // Generate the contents shared_ptr contents = m_contents->clone(); contents->setContentTypeHint(getContentType()); @@ -498,16 +518,15 @@ void body::generateImpl } -size_t body::getGeneratedSize(const generationContext& ctx) -{ +size_t body::getGeneratedSize(const generationContext& ctx) { + // MIME-Multipart - if (getPartCount() != 0) - { + if (getPartCount() != 0) { + size_t size = 0; // Size of parts and boundaries - for (size_t p = 0 ; p < getPartCount() ; ++p) - { + for (size_t p = 0 ; p < getPartCount() ; ++p) { size += 100; // boundary, CRLF... size += getPartAt(p)->getGeneratedSize(ctx); } @@ -515,42 +534,46 @@ size_t body::getGeneratedSize(const generationContext& ctx) // Size of prolog/epilog text const text prologText = getActualPrologText(ctx); - if (!prologText.isEmpty()) - { + if (!prologText.isEmpty()) { + std::ostringstream oss; utility::outputStreamAdapter osa(oss); - prologText.encodeAndFold(ctx, osa, 0, - NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); + prologText.encodeAndFold( + ctx, osa, 0, NULL, + text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE + ); size += oss.str().size(); } const text epilogText = getActualEpilogText(ctx); - if (!epilogText.isEmpty()) - { + if (!epilogText.isEmpty()) { + std::ostringstream oss; utility::outputStreamAdapter osa(oss); - epilogText.encodeAndFold(ctx, osa, 0, - NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE); + epilogText.encodeAndFold( + ctx, osa, 0, NULL, + text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE + ); size += oss.str().size(); } return size; - } + // Simple body - else - { - if (getEncoding() == m_contents->getEncoding()) - { + } else { + + if (getEncoding() == m_contents->getEncoding()) { + // No re-encoding has to be performed return m_contents->getLength(); - } - else - { + + } else { + shared_ptr srcEncoder = m_contents->getEncoding().getEncoder(); shared_ptr dstEncoder = getEncoding().getEncoder(); @@ -576,8 +599,8 @@ size_t body::getGeneratedSize(const generationContext& ctx) / "," / "-" / "." / "/" / ":" / "=" / "?" */ -const string body::generateRandomBoundaryString() -{ +const string body::generateRandomBoundaryString() { + // 64 characters that can be _safely_ used in a boundary string static const char bchars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-+"; @@ -603,43 +626,43 @@ const string body::generateRandomBoundaryString() unsigned int r = utility::random::getTime(); unsigned int m = static_cast (sizeof(unsigned int)); - for (size_t i = 2 ; i < (sizeof(boundary) / sizeof(boundary[0]) - 1) ; ++i) - { + for (size_t i = 2 ; i < (sizeof(boundary) / sizeof(boundary[0]) - 1) ; ++i) { + boundary[i] = bchars[r & 63]; r >>= 6; - if (--m == 0) - { + if (--m == 0) { r = utility::random::getNext(); m = static_cast (sizeof(unsigned int)); } } - return (string(boundary)); + return string(boundary); } -bool body::isValidBoundary(const string& boundary) -{ +bool body::isValidBoundary(const string& boundary) { + static const string validChars("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'()+_,-./:=?"); const string::const_iterator end = boundary.end(); bool valid = false; - if (boundary.length() > 0 && boundary.length() < 70) - { + if (boundary.length() > 0 && boundary.length() < 70) { + const char last = *(end - 1); - if (!(last == ' ' || last == '\t' || last == '\n')) - { + if (!(last == ' ' || last == '\t' || last == '\n')) { + valid = true; - for (string::const_iterator i = boundary.begin() ; valid && i != end ; ++i) + for (string::const_iterator i = boundary.begin() ; valid && i != end ; ++i) { valid = (validChars.find_first_of(*i) != string::npos); + } } } - return (valid); + return valid; } @@ -648,8 +671,8 @@ bool body::isValidBoundary(const string& boundary) // -void body::setContentType(const mediaType& type, const charset& chset) -{ +void body::setContentType(const mediaType& type, const charset& chset) { + shared_ptr ctf = dynamicCast (m_part->getHeader()->ContentType()); @@ -658,92 +681,93 @@ void body::setContentType(const mediaType& type, const charset& chset) } -void body::setContentType(const mediaType& type) -{ +void body::setContentType(const mediaType& type) { + m_part->getHeader()->ContentType()->setValue(type); } -const mediaType body::getContentType() const -{ +const mediaType body::getContentType() const { + shared_ptr ctf = m_part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + return *ctf->getValue (); - } - else - { + + } else { + // Defaults to "text/plain" (RFC-1521) - return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); + return mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN); } } -void body::setCharset(const charset& chset) -{ +void body::setCharset(const charset& chset) { + shared_ptr ctf = m_part->getHeader()->findField (fields::CONTENT_TYPE); // If a Content-Type field exists, set charset - if (ctf) - { + if (ctf) { + ctf->setCharset(chset); - } + // Else, create a new Content-Type field of default type "text/plain" // and set charset on it - else - { + } else { + setContentType(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), chset); } } -const charset body::getCharset() const -{ +const charset body::getCharset() const { + const shared_ptr ctf = m_part->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { - if (ctf->hasCharset()) - { - return (ctf->getCharset()); - } - else - { + if (ctf) { + + if (ctf->hasCharset()) { + + return ctf->getCharset(); + + } else { + // Defaults to "us-ascii" (RFC-1521) - return (vmime::charset(charsets::US_ASCII)); + return vmime::charset(charsets::US_ASCII); } - } - else - { + + } else { + // Defaults to "us-ascii" (RFC-1521) - return (vmime::charset(charsets::US_ASCII)); + return vmime::charset(charsets::US_ASCII); } } -void body::setEncoding(const encoding& enc) -{ +void body::setEncoding(const encoding& enc) { + m_part->getHeader()->ContentTransferEncoding()->setValue(enc); } -const encoding body::getEncoding() const -{ +const encoding body::getEncoding() const { + shared_ptr cef = m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING); - if (cef) - { + if (cef) { + return *cef->getValue (); - } - else - { - if (m_contents->isEncoded()) + + } else { + + if (m_contents->isEncoded()) { return m_contents->getEncoding(); + } } // Defaults to "7bit" (RFC-1521) @@ -751,37 +775,37 @@ const encoding body::getEncoding() const } -void body::setParentPart(bodyPart* parent) -{ +void body::setParentPart(bodyPart* parent) { + m_part = parent; for (std::vector >::iterator it = m_parts.begin() ; - it != m_parts.end() ; ++it) - { + it != m_parts.end() ; ++it) { + shared_ptr childPart = *it; parent->importChildPart(childPart); } } -bool body::isRootPart() const -{ - return (m_part == NULL || m_part->getParentPart() == NULL); +bool body::isRootPart() const { + + return !m_part || !m_part->getParentPart(); } -shared_ptr body::clone() const -{ +shared_ptr body::clone() const { + shared_ptr bdy = make_shared (); bdy->copyFrom(*this); - return (bdy); + return bdy; } -void body::copyFrom(const component& other) -{ +void body::copyFrom(const component& other) { + const body& bdy = dynamic_cast (other); m_prologText = bdy.m_prologText; @@ -791,8 +815,8 @@ void body::copyFrom(const component& other) removeAllParts(); - for (size_t p = 0 ; p < bdy.getPartCount() ; ++p) - { + for (size_t p = 0 ; p < bdy.getPartCount() ; ++p) { + shared_ptr part = m_part->createChildPart(); part->copyFrom(*bdy.getPartAt(p)); @@ -802,68 +826,79 @@ void body::copyFrom(const component& other) } -body& body::operator=(const body& other) -{ +body& body::operator=(const body& other) { + copyFrom(other); - return (*this); + return *this; } -const string& body::getPrologText() const -{ - return (m_prologText); +const string& body::getPrologText() const { + + return m_prologText; } -void body::setPrologText(const string& prologText) -{ +void body::setPrologText(const string& prologText) { + m_prologText = prologText; } -const string& body::getEpilogText() const -{ - return (m_epilogText); +const string& body::getEpilogText() const { + + return m_epilogText; } -void body::setEpilogText(const string& epilogText) -{ +void body::setEpilogText(const string& epilogText) { + m_epilogText = epilogText; } -const shared_ptr body::getContents() const -{ - return (m_contents); +const shared_ptr body::getContents() const { + + return m_contents; } -void body::setContents(const shared_ptr & contents) -{ +void body::setContents(const shared_ptr & contents) { + m_contents = contents; } -void body::setContents(const shared_ptr & contents, const mediaType& type) -{ +void body::setContents( + const shared_ptr & contents, + const mediaType& type +) { + m_contents = contents; setContentType(type); } -void body::setContents(const shared_ptr & contents, const mediaType& type, const charset& chset) -{ +void body::setContents( + const shared_ptr & contents, + const mediaType& type, + const charset& chset +) { + m_contents = contents; setContentType(type, chset); } -void body::setContents(const shared_ptr & contents, const mediaType& type, - const charset& chset, const encoding& enc) -{ +void body::setContents( + const shared_ptr & contents, + const mediaType& type, + const charset& chset, + const encoding& enc +) { + m_contents = contents; setContentType(type, chset); @@ -871,16 +906,17 @@ void body::setContents(const shared_ptr & contents, const } -void body::initNewPart(const shared_ptr & part) -{ +void body::initNewPart(const shared_ptr & part) { + // A part can be in only one body at the same time: if part is // already attached to a parent part, remove it from the current // parent part - if (part->getParentPart()) + if (part->getParentPart()) { part->getParentPart()->getBody()->removePart(part); + } + + if (m_part) { - if (m_part != NULL) - { m_part->importChildPart(part); shared_ptr
hdr = m_part->getHeader(); @@ -889,29 +925,30 @@ void body::initNewPart(const shared_ptr & part) shared_ptr ctf = hdr->findField (fields::CONTENT_TYPE); - if (ctf) - { - if (ctf->hasBoundary()) - { + if (ctf) { + + if (ctf->hasBoundary()) { + const string boundary = ctf->getBoundary(); - if (boundary.empty() || !isValidBoundary(boundary)) + if (boundary.empty() || !isValidBoundary(boundary)) { ctf->setBoundary(generateRandomBoundaryString()); - } - else - { + } + + } else { + // No "boundary" parameter: generate a random one. ctf->setBoundary(generateRandomBoundaryString()); } - if (ctf->getValue ()->getType() != mediaTypes::MULTIPART) - { + if (ctf->getValue ()->getType() != mediaTypes::MULTIPART) { + // Warning: multi-part body but the Content-Type is // not specified as "multipart/..." } - } - else - { + + } else { + // No "Content-Type" field: create a new one and generate // a random boundary string. ctf = hdr->getField (fields::CONTENT_TYPE); @@ -923,135 +960,150 @@ void body::initNewPart(const shared_ptr & part) } -void body::appendPart(const shared_ptr & part) -{ +void body::appendPart(const shared_ptr & part) { + initNewPart(part); m_parts.push_back(part); } -void body::insertPartBefore(const shared_ptr & beforePart, const shared_ptr & part) -{ +void body::insertPartBefore( + const shared_ptr & beforePart, + const shared_ptr & part +) { + initNewPart(part); - const std::vector >::iterator it = std::find - (m_parts.begin(), m_parts.end(), beforePart); + const std::vector >::iterator it = std::find( + m_parts.begin(), m_parts.end(), beforePart + ); - if (it == m_parts.end()) + if (it == m_parts.end()) { throw exceptions::no_such_part(); + } m_parts.insert(it, part); } -void body::insertPartBefore(const size_t pos, const shared_ptr & part) -{ +void body::insertPartBefore( + const size_t pos, + const shared_ptr & part +) { + initNewPart(part); m_parts.insert(m_parts.begin() + pos, part); } -void body::insertPartAfter(const shared_ptr & afterPart, const shared_ptr & part) -{ +void body::insertPartAfter( + const shared_ptr & afterPart, + const shared_ptr & part +) { + initNewPart(part); - const std::vector >::iterator it = std::find - (m_parts.begin(), m_parts.end(), afterPart); + const std::vector >::iterator it = std::find( + m_parts.begin(), m_parts.end(), afterPart + ); - if (it == m_parts.end()) + if (it == m_parts.end()) { throw exceptions::no_such_part(); + } m_parts.insert(it + 1, part); } -void body::insertPartAfter(const size_t pos, const shared_ptr & part) -{ +void body::insertPartAfter(const size_t pos, const shared_ptr & part) { + initNewPart(part); m_parts.insert(m_parts.begin() + pos + 1, part); } -void body::removePart(const shared_ptr & part) -{ - const std::vector >::iterator it = std::find - (m_parts.begin(), m_parts.end(), part); +void body::removePart(const shared_ptr & part) { - if (it == m_parts.end()) + const std::vector >::iterator it = std::find( + m_parts.begin(), m_parts.end(), part + ); + + if (it == m_parts.end()) { throw exceptions::no_such_part(); + } m_parts.erase(it); } -void body::removePart(const size_t pos) -{ +void body::removePart(const size_t pos) { + m_parts.erase(m_parts.begin() + pos); } -void body::removeAllParts() -{ +void body::removeAllParts() { + m_parts.clear(); } -size_t body::getPartCount() const -{ - return (m_parts.size()); +size_t body::getPartCount() const { + + return m_parts.size(); } -bool body::isEmpty() const -{ - return (m_parts.size() == 0); +bool body::isEmpty() const { + + return m_parts.size() == 0; } -shared_ptr body::getPartAt(const size_t pos) -{ - return (m_parts[pos]); +shared_ptr body::getPartAt(const size_t pos) { + + return m_parts[pos]; } -const shared_ptr body::getPartAt(const size_t pos) const -{ - return (m_parts[pos]); +const shared_ptr body::getPartAt(const size_t pos) const { + + return m_parts[pos]; } -const std::vector > body::getPartList() const -{ +const std::vector > body::getPartList() const { + std::vector > list; list.reserve(m_parts.size()); for (std::vector >::const_iterator it = m_parts.begin() ; - it != m_parts.end() ; ++it) - { + it != m_parts.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > body::getPartList() -{ - return (m_parts); +const std::vector > body::getPartList() { + + return m_parts; } -const std::vector > body::getChildComponents() -{ +const std::vector > body::getChildComponents() { + std::vector > list; copy_vector(m_parts, list); - return (list); + return list; } diff --git a/src/vmime/body.hpp b/src/vmime/body.hpp index 24f010b4..7ece000e 100644 --- a/src/vmime/body.hpp +++ b/src/vmime/body.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,7 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { class bodyPart; @@ -46,9 +45,8 @@ class bodyPart; /** Body section of a MIME part. */ +class VMIME_EXPORT body : public component { -class VMIME_EXPORT body : public component -{ friend class bodyPart; public: @@ -68,7 +66,10 @@ public: * @param part part to insert * @throw exceptions::no_such_part if the part is not in the list */ - void insertPartBefore(const shared_ptr & beforePart, const shared_ptr & part); + void insertPartBefore( + const shared_ptr & beforePart, + const shared_ptr & part + ); /** Insert a new part before the specified position. * @@ -84,7 +85,10 @@ public: * @param part part to insert * @throw exceptions::no_such_part if the part is not in the list */ - void insertPartAfter(const shared_ptr & afterPart, const shared_ptr & part); + void insertPartAfter( + const shared_ptr & afterPart, + const shared_ptr & part + ); /** Insert a new part after the specified position. * @@ -189,7 +193,10 @@ public: * @param contents new body contents * @param type type of contents */ - void setContents(const shared_ptr & contents, const mediaType& type); + void setContents( + const shared_ptr & contents, + const mediaType& type + ); /** Set the body contents, type and charset. * @@ -197,7 +204,11 @@ public: * @param type type of contents * @param chset charset of contents */ - void setContents(const shared_ptr & contents, const mediaType& type, const charset& chset); + void setContents( + const shared_ptr & contents, + const mediaType& type, + const charset& chset + ); /** Set the body contents, type, charset and encoding. * @@ -206,8 +217,12 @@ public: * @param chset charset of contents * @param enc contents encoding */ - void setContents(const shared_ptr & contents, const mediaType& type, - const charset& chset, const encoding& enc); + void setContents( + const shared_ptr & contents, + const mediaType& type, + const charset& chset, + const encoding& enc + ); /** Set the MIME type and charset of contents. * If a charset is defined, it will not be modified. @@ -317,24 +332,30 @@ protected: * before the CRLF or "--" which follows) * @return the position of the boundary string, or npos if not found */ - size_t findNextBoundaryPosition - (const shared_ptr & parser, const string& boundary, - const size_t position, const size_t end, - size_t* boundaryStart, size_t* boundaryEnd); + size_t findNextBoundaryPosition( + const shared_ptr & parser, + const string& boundary, + const size_t position, + const size_t end, + size_t* boundaryStart, + size_t* boundaryEnd + ); // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const shared_ptr & parser, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/bodyPart.cpp b/src/vmime/bodyPart.cpp index c215eb80..ff81994d 100644 --- a/src/vmime/bodyPart.cpp +++ b/src/vmime/bodyPart.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,23 +24,26 @@ #include "vmime/bodyPart.hpp" -namespace vmime -{ +namespace vmime { bodyPart::bodyPart() : m_header(make_shared
()), m_body(make_shared ()), - m_parent() -{ + m_parent() { + m_body->setParentPart(this); } -void bodyPart::parseImpl - (const parsingContext& ctx, const shared_ptr & parser, - const size_t position, const size_t end, size_t* newPosition) -{ +void bodyPart::parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition +) { + // Parse the headers size_t pos = position; m_header->parse(ctx, parser, pos, end, &pos); @@ -50,34 +53,39 @@ void bodyPart::parseImpl setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void bodyPart::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t /* curLinePos */, size_t* newLinePos) const -{ +void bodyPart::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t /* curLinePos */, + size_t* newLinePos +) const { + m_header->generate(ctx, os); os << CRLF; m_body->generate(ctx, os); - if (newLinePos) + if (newLinePos) { *newLinePos = 0; + } } -size_t bodyPart::getGeneratedSize(const generationContext& ctx) -{ +size_t bodyPart::getGeneratedSize(const generationContext& ctx) { + return m_header->getGeneratedSize(ctx) + 2 /* CRLF */ + m_body->getGeneratedSize(ctx); } -shared_ptr bodyPart::clone() const -{ +shared_ptr bodyPart::clone() const { + shared_ptr p = make_shared (); p->m_parent = NULL; @@ -85,12 +93,12 @@ shared_ptr bodyPart::clone() const p->m_header->copyFrom(*m_header); p->m_body->copyFrom(*m_body); - return (p); + return p; } -void bodyPart::copyFrom(const component& other) -{ +void bodyPart::copyFrom(const component& other) { + const bodyPart& bp = dynamic_cast (other); m_header->copyFrom(*(bp.m_header)); @@ -98,70 +106,71 @@ void bodyPart::copyFrom(const component& other) } -bodyPart& bodyPart::operator=(const bodyPart& other) -{ +bodyPart& bodyPart::operator=(const bodyPart& other) { + copyFrom(other); - return (*this); + return *this; } -const shared_ptr bodyPart::getHeader() const -{ - return (m_header); +const shared_ptr bodyPart::getHeader() const { + + return m_header; } -shared_ptr
bodyPart::getHeader() -{ - return (m_header); +shared_ptr
bodyPart::getHeader() { + + return m_header; } -void bodyPart::setHeader(const shared_ptr
& h) -{ +void bodyPart::setHeader(const shared_ptr
& h) { + m_header = h; } -const shared_ptr bodyPart::getBody() const -{ - return (m_body); +const shared_ptr bodyPart::getBody() const { + + return m_body; } -shared_ptr bodyPart::getBody() -{ - return (m_body); +shared_ptr bodyPart::getBody() { + + return m_body; } -void bodyPart::setBody(const shared_ptr & b) -{ +void bodyPart::setBody(const shared_ptr & b) { + bodyPart* oldPart = b->m_part; m_body = b; m_body->setParentPart(this); // A body is associated to one and only one part - if (oldPart != NULL) + if (oldPart) { oldPart->setBody(make_shared ()); + } } -bodyPart* bodyPart::getParentPart() -{ +bodyPart* bodyPart::getParentPart() { + return m_parent; } -const bodyPart* bodyPart::getParentPart() const -{ +const bodyPart* bodyPart::getParentPart() const { + return m_parent; } -shared_ptr bodyPart::createChildPart() -{ +shared_ptr bodyPart::createChildPart() { + shared_ptr part = make_shared (); part->m_parent = this; @@ -169,22 +178,21 @@ shared_ptr bodyPart::createChildPart() } -void bodyPart::importChildPart(const shared_ptr & part) -{ +void bodyPart::importChildPart(const shared_ptr & part) { + part->m_parent = this; } -const std::vector > bodyPart::getChildComponents() -{ +const std::vector > bodyPart::getChildComponents() { + std::vector > list; list.push_back(m_header); list.push_back(m_body); - return (list); + return list; } } // vmime - diff --git a/src/vmime/bodyPart.hpp b/src/vmime/bodyPart.hpp index 729af253..f63b3675 100644 --- a/src/vmime/bodyPart.hpp +++ b/src/vmime/bodyPart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,15 +32,13 @@ #include "vmime/body.hpp" -namespace vmime -{ +namespace vmime { /** A MIME part. */ +class VMIME_EXPORT bodyPart : public component { -class VMIME_EXPORT bodyPart : public component -{ friend class body; public: @@ -134,18 +132,20 @@ protected: void importChildPart(const shared_ptr & part); // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const shared_ptr & parser, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/bodyPartAttachment.cpp b/src/vmime/bodyPartAttachment.cpp index 07a92d12..01b306e3 100644 --- a/src/vmime/bodyPartAttachment.cpp +++ b/src/vmime/bodyPartAttachment.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,55 +24,57 @@ #include "vmime/bodyPartAttachment.hpp" -namespace vmime -{ +namespace vmime { bodyPartAttachment::bodyPartAttachment(const shared_ptr & part) - : m_part(part) -{ + : m_part(part) { + } -const mediaType bodyPartAttachment::getType() const -{ +const mediaType bodyPartAttachment::getType() const { + shared_ptr ctf = getContentType(); - if (ctf) - { + if (ctf) { + return *ctf->getValue (); - } - else - { + + } else { + // No "Content-type" field: assume "application/octet-stream". - return mediaType(mediaTypes::APPLICATION, - mediaTypes::APPLICATION_OCTET_STREAM); + return mediaType( + mediaTypes::APPLICATION, + mediaTypes::APPLICATION_OCTET_STREAM + ); } } -const word bodyPartAttachment::getName() const -{ +const word bodyPartAttachment::getName() const { + word name; // Try the 'filename' parameter of 'Content-Disposition' field shared_ptr cdf = getContentDisposition(); - if (cdf && cdf->hasFilename()) - { + if (cdf && cdf->hasFilename()) { + name = cdf->getFilename(); - } + // Try the 'name' parameter of 'Content-Type' field - else - { + } else { + shared_ptr ctf = getContentType(); - if (ctf) - { + if (ctf) { + shared_ptr prm = ctf->findParameter("name"); - if (prm != NULL) + if (prm) { name = prm->getValue(); + } } } @@ -80,19 +82,19 @@ const word bodyPartAttachment::getName() const } -const text bodyPartAttachment::getDescription() const -{ +const text bodyPartAttachment::getDescription() const { + text description; shared_ptr cd = getHeader()->findField(fields::CONTENT_DESCRIPTION); - if (cd) - { + if (cd) { + description = *cd->getValue (); - } - else - { + + } else { + // No description available. } @@ -100,47 +102,46 @@ const text bodyPartAttachment::getDescription() const } -const encoding bodyPartAttachment::getEncoding() const -{ +const encoding bodyPartAttachment::getEncoding() const { + return m_part->getBody()->getEncoding(); } -const shared_ptr bodyPartAttachment::getData() const -{ +const shared_ptr bodyPartAttachment::getData() const { + return m_part->getBody()->getContents(); } -shared_ptr bodyPartAttachment::getPart() const -{ +shared_ptr bodyPartAttachment::getPart() const { + return m_part; } -shared_ptr bodyPartAttachment::getHeader() const -{ +shared_ptr bodyPartAttachment::getHeader() const { + return m_part->getHeader(); } -shared_ptr bodyPartAttachment::getContentDisposition() const -{ +shared_ptr bodyPartAttachment::getContentDisposition() const { + return getHeader()->findField (fields::CONTENT_DISPOSITION); } -shared_ptr bodyPartAttachment::getContentType() const -{ +shared_ptr bodyPartAttachment::getContentType() const { + return getHeader()->findField (fields::CONTENT_TYPE); } -void bodyPartAttachment::generateIn(const shared_ptr & /* parent */) const -{ +void bodyPartAttachment::generateIn(const shared_ptr & /* parent */) const { + // Not used } } // vmime - diff --git a/src/vmime/bodyPartAttachment.hpp b/src/vmime/bodyPartAttachment.hpp index 43848bd3..974e2f8c 100644 --- a/src/vmime/bodyPartAttachment.hpp +++ b/src/vmime/bodyPartAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,14 +34,13 @@ #include "vmime/contentTypeField.hpp" -namespace vmime -{ +namespace vmime { /** An attachment related to a local body part. */ -class VMIME_EXPORT bodyPartAttachment : public attachment -{ +class VMIME_EXPORT bodyPartAttachment : public attachment { + public: bodyPartAttachment(const shared_ptr & part); @@ -75,4 +74,3 @@ private: #endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED - diff --git a/src/vmime/charset.cpp b/src/vmime/charset.cpp index 1a291106..8828c563 100644 --- a/src/vmime/charset.cpp +++ b/src/vmime/charset.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,74 +32,93 @@ -namespace vmime -{ +namespace vmime { charset::charset() - : m_name(charsets::US_ASCII) -{ + : m_name(charsets::US_ASCII) { + } charset::charset(const string& name) - : m_name(name) -{ + : m_name(name) { + // If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv - if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) + if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) { m_name = "utf-7"; + } } charset::charset(const char* name) - : m_name(name) -{ + : m_name(name) { + } -void charset::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ - m_name = utility::stringUtils::trim - (string(buffer.begin() + position, buffer.begin() + end)); +void charset::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + + m_name = utility::stringUtils::trim( + string(buffer.begin() + position, buffer.begin() + end) + ); // If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv - if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) + if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) { m_name = "utf-7"; + } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void charset::generateImpl - (const generationContext& /* ctx */, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void charset::generateImpl( + const generationContext& /* ctx */, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + os << m_name; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + m_name.length(); + } } -void charset::convert(utility::inputStream& in, utility::outputStream& out, - const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ +void charset::convert( + utility::inputStream& in, + utility::outputStream& out, + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + shared_ptr conv = charsetConverter::create(source, dest, opts); conv->convert(in, out); } -void charset::convert(const string& in, string& out, const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ - if (source == dest) - { +void charset::convert( + const string& in, + string& out, + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + + if (source == dest) { out = in; return; } @@ -109,27 +128,26 @@ void charset::convert(const string& in, string& out, const charset& source, cons } -bool charset::isValidText - (const string& text, string::size_type* firstInvalidByte) const -{ +bool charset::isValidText(const string& text, string::size_type* firstInvalidByte) const { + charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = false; charsetConverter::status st; - try - { + try { + std::string out; // Try converting to UTF-8 shared_ptr conv = charsetConverter::create(*this, vmime::charset("utf-8"), opts); conv->convert(text, out, &st); - } - catch (exceptions::illegal_byte_sequence_for_charset& e) - { + + } catch (exceptions::illegal_byte_sequence_for_charset& e) { + // An illegal byte sequence was found in the input buffer - if (firstInvalidByte) - { + if (firstInvalidByte) { + if (st.inputBytesRead < text.length()) *firstInvalidByte = st.inputBytesRead; else @@ -139,77 +157,79 @@ bool charset::isValidText return false; } - if (firstInvalidByte) + if (firstInvalidByte) { *firstInvalidByte = text.length(); + } return true; } -const charset charset::getLocalCharset() -{ - return (platform::getHandler()->getLocalCharset()); +const charset charset::getLocalCharset() { + + return platform::getHandler()->getLocalCharset(); } -charset& charset::operator=(const charset& other) -{ +charset& charset::operator=(const charset& other) { + copyFrom(other); - return (*this); + return *this; } -bool charset::operator==(const charset& value) const -{ - return (utility::stringUtils::isStringEqualNoCase(m_name, value.m_name)); +bool charset::operator==(const charset& value) const { + + return utility::stringUtils::isStringEqualNoCase(m_name, value.m_name); } -bool charset::operator!=(const charset& value) const -{ +bool charset::operator!=(const charset& value) const { + return !(*this == value); } -shared_ptr charset::clone() const -{ +shared_ptr charset::clone() const { + return make_shared (m_name); } -const string& charset::getName() const -{ - return (m_name); +const string& charset::getName() const { + + return m_name; } -void charset::copyFrom(const component& other) -{ +void charset::copyFrom(const component& other) { + m_name = dynamic_cast (other).m_name; } -const std::vector > charset::getChildComponents() -{ +const std::vector > charset::getChildComponents() { + return std::vector >(); } // Explicitly force encoding for some charsets -struct CharsetEncodingEntry -{ +struct CharsetEncodingEntry { + CharsetEncodingEntry(const string& charset_, const string& encoding_) - : charset(charset_), encoding(encoding_) - { + : charset(charset_), encoding(encoding_) { + } const string charset; const string encoding; }; -CharsetEncodingEntry g_charsetEncodingMap[] = -{ + +CharsetEncodingEntry g_charsetEncodingMap[] = { + // Use QP encoding for ISO-8859-x charsets CharsetEncodingEntry("iso-8859", encodingTypes::QUOTED_PRINTABLE), CharsetEncodingEntry("iso8859", encodingTypes::QUOTED_PRINTABLE), @@ -226,15 +246,16 @@ CharsetEncodingEntry g_charsetEncodingMap[] = }; -bool charset::getRecommendedEncoding(encoding& enc) const -{ +bool charset::getRecommendedEncoding(encoding& enc) const { + // Special treatment for some charsets const string cset = utility::stringUtils::toLower(getName()); - for (unsigned int i = 0 ; i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ; ++i) - { - if (cset.find(g_charsetEncodingMap[i].charset) != string::npos) - { + for (unsigned int i = 0 ; + i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ; + ++i) { + + if (cset.find(g_charsetEncodingMap[i].charset) != string::npos) { enc = g_charsetEncodingMap[i].encoding; return true; } diff --git a/src/vmime/charset.hpp b/src/vmime/charset.hpp index 2b8d6109..61f9bd69 100644 --- a/src/vmime/charset.hpp +++ b/src/vmime/charset.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,8 +32,7 @@ #include "vmime/component.hpp" -namespace vmime -{ +namespace vmime { class encoding; // forward reference @@ -41,9 +40,8 @@ class encoding; // forward reference /** Charset description (basic type). */ +class VMIME_EXPORT charset : public component { -class VMIME_EXPORT charset : public component -{ public: charset(); @@ -102,9 +100,13 @@ public: * @throws exceptions::charset_conv_error if an unexpected error occurred * during the conversion */ - static void convert(const string& in, string& out, - const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + static void convert( + const string& in, + string& out, + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); /** Convert the contents of an input stream in a specified charset * to another charset and write the result to an output stream. @@ -121,9 +123,13 @@ public: * @throws exceptions::charset_conv_error if an unexpected error occurred * during the conversion */ - static void convert(utility::inputStream& in, utility::outputStream& out, - const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + static void convert( + utility::inputStream& in, + utility::outputStream& out, + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); /** Checks whether the specified text is valid in this charset. * @@ -147,18 +153,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/charsetConverter.cpp b/src/vmime/charsetConverter.cpp index 525a71ec..96bc3b8f 100644 --- a/src/vmime/charsetConverter.cpp +++ b/src/vmime/charsetConverter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,25 +26,26 @@ #include "vmime/charsetConverter_idna.hpp" -namespace vmime -{ +namespace vmime { // static -shared_ptr charsetConverter::create - (const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ - if (source == "idna" || dest == "idna") +shared_ptr charsetConverter::create( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + + if (source == "idna" || dest == "idna") { return make_shared (source, dest, opts); - else + } else { return createGenericConverter(source, dest, opts); + } } charsetConverter::status::status() - : inputBytesRead(0), outputBytesWritten(0) -{ + : inputBytesRead(0), outputBytesWritten(0) { } diff --git a/src/vmime/charsetConverter.hpp b/src/vmime/charsetConverter.hpp index 182cc879..2cde4b56 100644 --- a/src/vmime/charsetConverter.hpp +++ b/src/vmime/charsetConverter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,12 +33,10 @@ #include "vmime/utility/filteredStream.hpp" -namespace vmime -{ +namespace vmime { -namespace utility -{ +namespace utility { /** A filtered output stream which applies a charset conversion @@ -52,9 +50,8 @@ namespace utility * 'silentlyReplaceInvalidSequences' flag is set to false in * the charsetConverterOptions. */ +class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream { -class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream -{ }; @@ -63,15 +60,14 @@ class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream /** Convert between charsets. */ +class VMIME_EXPORT charsetConverter : public object { -class VMIME_EXPORT charsetConverter : public object -{ public: /** Holds information about a conversion. */ - struct status - { + struct status { + status(); @@ -91,9 +87,11 @@ public: * @param dest output charset * @param opts conversion options */ - static shared_ptr create - (const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + static shared_ptr create( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); /** Convert a string buffer from one charset to another * charset (in-memory conversion) @@ -128,7 +126,11 @@ public: * @throws exceptions::charset_conv_error if an unexpected error occurred * during the conversion */ - virtual void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL) = 0; + virtual void convert( + utility::inputStream& in, + utility::outputStream& out, + status* st = NULL + ) = 0; /** Returns a filtered output stream which applies a charset * conversion to input bytes. Please note that it may not be @@ -138,15 +140,19 @@ public: * @param opts conversion options * @return a filtered output stream, or NULL if not supported */ - virtual shared_ptr getFilteredOutputStream - (utility::outputStream& os, - const charsetConverterOptions& opts = charsetConverterOptions()) = 0; + virtual shared_ptr + getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts = charsetConverterOptions() + ) = 0; private: - static shared_ptr createGenericConverter - (const charset& source, const charset& dest, - const charsetConverterOptions& opts); + static shared_ptr createGenericConverter( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts + ); }; diff --git a/src/vmime/charsetConverterOptions.cpp b/src/vmime/charsetConverterOptions.cpp index 4b0814af..a18a928d 100644 --- a/src/vmime/charsetConverterOptions.cpp +++ b/src/vmime/charsetConverterOptions.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,14 +24,13 @@ #include "vmime/charsetConverterOptions.hpp" -namespace vmime -{ +namespace vmime { charsetConverterOptions::charsetConverterOptions() : silentlyReplaceInvalidSequences(true), - invalidSequence("?") -{ + invalidSequence("?") { + } diff --git a/src/vmime/charsetConverterOptions.hpp b/src/vmime/charsetConverterOptions.hpp index e07d30b2..567e0048 100644 --- a/src/vmime/charsetConverterOptions.hpp +++ b/src/vmime/charsetConverterOptions.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/base.hpp" -namespace vmime -{ +namespace vmime { /** Options for charset conversion. */ +class VMIME_EXPORT charsetConverterOptions : public object { -class VMIME_EXPORT charsetConverterOptions : public object -{ public: charsetConverterOptions(); diff --git a/src/vmime/charsetConverter_iconv.cpp b/src/vmime/charsetConverter_iconv.cpp index eebc229b..5c4cc171 100644 --- a/src/vmime/charsetConverter_iconv.cpp +++ b/src/vmime/charsetConverter_iconv.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,8 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -extern "C" -{ +extern "C" { + #ifndef VMIME_BUILDING_DOC #include @@ -45,8 +45,8 @@ extern "C" // second parameter may or may not be 'const'). This relies on the compiler // for choosing the right type. - class ICONV_IN_TYPE - { + class ICONV_IN_TYPE { + public: ICONV_IN_TYPE(const char** ptr) : m_ptr(ptr) { } @@ -62,8 +62,8 @@ extern "C" const char** m_ptr; }; - class ICONV_OUT_TYPE - { + class ICONV_OUT_TYPE { + public: ICONV_OUT_TYPE(char** ptr) : m_ptr(ptr) { } @@ -85,9 +85,12 @@ extern "C" // Output replacement char when an invalid sequence is encountered template -void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd, - const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions()) -{ +void outputInvalidChar( + OUTPUT_CLASS& out, + ICONV_DESC cd, + const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions() +) { + const char* invalidCharIn = opts.invalidSequence.c_str(); vmime::size_t invalidCharInLen = opts.invalidSequence.length(); @@ -96,36 +99,43 @@ void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd, vmime::size_t invalidCharOutLen = 16; if (iconv(cd, ICONV_IN_TYPE(&invalidCharIn), &invalidCharInLen, - ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast (-1)) - { + ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast (-1)) { + out.write(invalidCharOutBuffer, 16 - invalidCharOutLen); } } -namespace vmime -{ +namespace vmime { // static -shared_ptr charsetConverter::createGenericConverter - (const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ +shared_ptr charsetConverter::createGenericConverter( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + return make_shared (source, dest, opts); } -charsetConverter_iconv::charsetConverter_iconv - (const charset& source, const charset& dest, const charsetConverterOptions& opts) - : m_desc(NULL), m_source(source), m_dest(dest), m_options(opts) -{ +charsetConverter_iconv::charsetConverter_iconv( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) + : m_desc(NULL), + m_source(source), + m_dest(dest), + m_options(opts) { + // Get an iconv descriptor const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str()); - if (cd != reinterpret_cast (-1)) - { + if (cd != reinterpret_cast (-1)) { + iconv_t* p = new iconv_t; *p= cd; @@ -134,10 +144,10 @@ charsetConverter_iconv::charsetConverter_iconv } -charsetConverter_iconv::~charsetConverter_iconv() -{ - if (m_desc != NULL) - { +charsetConverter_iconv::~charsetConverter_iconv() { + + if (m_desc) { + // Close iconv handle iconv_close(*static_cast (m_desc)); @@ -147,14 +157,19 @@ charsetConverter_iconv::~charsetConverter_iconv() } -void charsetConverter_iconv::convert - (utility::inputStream& in, utility::outputStream& out, status* st) -{ - if (st) - new (st) status(); +void charsetConverter_iconv::convert( + utility::inputStream& in, + utility::outputStream& out, + status* st +) { - if (m_desc == NULL) + if (st) { + new (st) status(); + } + + if (!m_desc) { throw exceptions::charset_conv_error("Cannot initialize converter."); + } const iconv_t cd = *static_cast (m_desc); @@ -165,8 +180,8 @@ void charsetConverter_iconv::convert bool prevIsInvalid = false; bool breakAfterNext = false; - while (true) - { + while (true) { + // Fullfill the buffer size_t inLength = static_cast (in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos); size_t outLength = sizeof(outBuffer); @@ -177,23 +192,23 @@ void charsetConverter_iconv::convert // Convert input bytes if (iconv(cd, ICONV_IN_TYPE(&inPtr), ptrLength, - ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) - { - if (st && inPtr) - { + ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) { + + if (st && inPtr) { st->inputBytesRead += (inPtr - inBuffer); st->outputBytesWritten += (outPtr - outBuffer); } // Illegal input sequence or input sequence has no equivalent // sequence in the destination charset. - if (prevIsInvalid) - { + if (prevIsInvalid) { + // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); - if (!m_options.silentlyReplaceInvalidSequences) + if (!m_options.silentlyReplaceInvalidSequences) { throw exceptions::illegal_byte_sequence_for_charset(); + } // Output a special character to indicate we don't known how to // convert the sequence at this position @@ -202,9 +217,9 @@ void charsetConverter_iconv::convert // Skip a byte and leave unconverted bytes in the input buffer std::copy(const_cast (inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer); inPos = inLength - 1; - } - else - { + + } else { + // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); @@ -212,17 +227,17 @@ void charsetConverter_iconv::convert std::copy(const_cast (inPtr), inBuffer + sizeof(inBuffer), inBuffer); inPos = inLength; - if (errno != E2BIG) + if (errno != E2BIG) { prevIsInvalid = true; + } } - } - else - { + + } else { + // Write successfully converted bytes out.write(outBuffer, sizeof(outBuffer) - outLength); - if (st && inPtr) - { + if (st && inPtr) { st->inputBytesRead += (inPtr - inBuffer); st->outputBytesWritten += (outPtr - outBuffer); } @@ -231,20 +246,23 @@ void charsetConverter_iconv::convert prevIsInvalid = false; } - if (breakAfterNext) + if (breakAfterNext) { break; + } // Check for end of data, loop again to flush stateful data from iconv - if (in.eof() && inPos == 0) + if (in.eof() && inPos == 0) { breakAfterNext = true; + } } } -void charsetConverter_iconv::convert(const string& in, string& out, status* st) -{ - if (st) +void charsetConverter_iconv::convert(const string& in, string& out, status* st) { + + if (st) { new (st) status(); + } out.clear(); @@ -258,9 +276,11 @@ void charsetConverter_iconv::convert(const string& in, string& out, status* st) shared_ptr - charsetConverter_iconv::getFilteredOutputStream - (utility::outputStream& os, const charsetConverterOptions& opts) -{ + charsetConverter_iconv::getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts + ) { + return make_shared (m_source, m_dest, &os, opts); } @@ -271,17 +291,23 @@ shared_ptr namespace utility { -charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv - (const charset& source, const charset& dest, outputStream* os, - const charsetConverterOptions& opts) - : m_desc(NULL), m_sourceCharset(source), m_destCharset(dest), - m_stream(*os), m_unconvCount(0), m_options(opts) -{ +charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv( + const charset& source, + const charset& dest, outputStream* os, + const charsetConverterOptions& opts +) + : m_desc(NULL), + m_sourceCharset(source), + m_destCharset(dest), + m_stream(*os), + m_unconvCount(0), + m_options(opts) { + // Get an iconv descriptor const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str()); - if (cd != reinterpret_cast (-1)) - { + if (cd != reinterpret_cast (-1)) { + iconv_t* p = new iconv_t; *p= cd; @@ -290,10 +316,10 @@ charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv } -charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() -{ - if (m_desc != NULL) - { +charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() { + + if (m_desc) { + // Close iconv handle iconv_close(*static_cast (m_desc)); @@ -303,17 +329,20 @@ charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() } -outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream() -{ +outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream() { + return m_stream; } -void charsetFilteredOutputStream_iconv::writeImpl - (const byte_t* const data, const size_t count) -{ - if (m_desc == NULL) +void charsetFilteredOutputStream_iconv::writeImpl( + const byte_t* const data, + const size_t count +) { + + if (!m_desc) { throw exceptions::charset_conv_error("Cannot initialize converter."); + } const iconv_t cd = *static_cast (m_desc); @@ -322,23 +351,26 @@ void charsetFilteredOutputStream_iconv::writeImpl // If there is some unconverted bytes left, add more data from this // chunk to see if it can now be converted. - while (m_unconvCount != 0 || curDataLen != 0) - { - if (m_unconvCount != 0) - { + while (m_unconvCount != 0 || curDataLen != 0) { + + if (m_unconvCount != 0) { + // Check if an incomplete input sequence is larger than the // input buffer size: should not happen except if something // in the input sequence is invalid. If so, output a special // character and skip one byte in the invalid sequence. - if (m_unconvCount >= sizeof(m_unconvBuffer)) - { - if (!m_options.silentlyReplaceInvalidSequences) + if (m_unconvCount >= sizeof(m_unconvBuffer)) { + + if (!m_options.silentlyReplaceInvalidSequences) { throw exceptions::illegal_byte_sequence_for_charset(); + } outputInvalidChar(m_stream, cd); - std::copy(m_unconvBuffer + 1, - m_unconvBuffer + m_unconvCount, m_unconvBuffer); + std::copy( + m_unconvBuffer + 1, + m_unconvBuffer + m_unconvCount, m_unconvBuffer + ); m_unconvCount--; } @@ -365,16 +397,18 @@ void charsetFilteredOutputStream_iconv::writeImpl const size_t inLength0 = inLength; if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, - ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) - { + ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) { + const size_t inputConverted = inLength0 - inLength; // Write successfully converted bytes m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength); // Shift unconverted bytes - std::copy(m_unconvBuffer + inputConverted, - m_unconvBuffer + m_unconvCount, m_unconvBuffer); + std::copy( + m_unconvBuffer + inputConverted, + m_unconvBuffer + m_unconvCount, m_unconvBuffer + ); m_unconvCount -= inputConverted; @@ -388,8 +422,9 @@ void charsetFilteredOutputStream_iconv::writeImpl m_unconvCount = 0; } - if (curDataLen == 0) + if (curDataLen == 0) { return; // no more data + } // Now, convert the current data buffer const byte_t* inPtr = curData; @@ -400,8 +435,8 @@ void charsetFilteredOutputStream_iconv::writeImpl const size_t inLength0 = inLength; if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, - ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) - { + ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) { + // Write successfully converted bytes m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength); @@ -412,17 +447,17 @@ void charsetFilteredOutputStream_iconv::writeImpl // Put one byte byte into the unconverted buffer so // that the next iteration fill it - if (curDataLen != 0) - { + if (curDataLen != 0) { + m_unconvCount = 1; m_unconvBuffer[0] = *curData; curData++; curDataLen--; } - } - else - { + + } else { + // Write successfully converted bytes m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength); @@ -433,18 +468,19 @@ void charsetFilteredOutputStream_iconv::writeImpl } -void charsetFilteredOutputStream_iconv::flush() -{ - if (m_desc == NULL) +void charsetFilteredOutputStream_iconv::flush() { + + if (!m_desc) { throw exceptions::charset_conv_error("Cannot initialize converter."); + } const iconv_t cd = *static_cast (m_desc); size_t offset = 0; // Process unconverted bytes - while (m_unconvCount != 0) - { + while (m_unconvCount != 0) { + // Try a conversion const byte_t* inPtr = m_unconvBuffer + offset; size_t inLength = m_unconvCount; @@ -453,32 +489,34 @@ void charsetFilteredOutputStream_iconv::flush() const size_t inLength0 = inLength; - if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) - { + if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, + ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast (-1)) { + const size_t inputConverted = inLength0 - inLength; // Skip a "blocking" character - if (inputConverted == 0) - { - if (!m_options.silentlyReplaceInvalidSequences) + if (inputConverted == 0) { + + if (!m_options.silentlyReplaceInvalidSequences) { throw exceptions::illegal_byte_sequence_for_charset(); + } outputInvalidChar(m_stream, cd); offset++; m_unconvCount--; - } - else - { + + } else { + // Write successfully converted bytes m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength); offset += inputConverted; m_unconvCount -= inputConverted; } - } - else - { + + } else { + // Write successfully converted bytes m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength); diff --git a/src/vmime/charsetConverter_iconv.hpp b/src/vmime/charsetConverter_iconv.hpp index e9a0f28a..c64813cd 100644 --- a/src/vmime/charsetConverter_iconv.hpp +++ b/src/vmime/charsetConverter_iconv.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,15 +34,13 @@ #include "vmime/charsetConverter.hpp" -namespace vmime -{ +namespace vmime { /** A generic charset converter which uses iconv library. */ +class charsetConverter_iconv : public charsetConverter { -class charsetConverter_iconv : public charsetConverter -{ public: /** Construct and initialize an iconv charset converter. @@ -51,17 +49,21 @@ public: * @param dest output charset * @param opts conversion options */ - charsetConverter_iconv(const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetConverter_iconv( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); ~charsetConverter_iconv(); void convert(const string& in, string& out, status* st = NULL); void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL); - shared_ptr getFilteredOutputStream - (utility::outputStream& os, - const charsetConverterOptions& opts = charsetConverterOptions()); + shared_ptr getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts = charsetConverterOptions() + ); private: @@ -77,8 +79,8 @@ private: namespace utility { -class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream -{ +class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream { + public: /** Construct a new filter for the specified output stream. @@ -88,9 +90,11 @@ public: * @param os stream into which write filtered data * @param opts conversion options */ - charsetFilteredOutputStream_iconv - (const charset& source, const charset& dest, outputStream* os, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetFilteredOutputStream_iconv( + const charset& source, + const charset& dest, outputStream* os, + const charsetConverterOptions& opts = charsetConverterOptions() + ); ~charsetFilteredOutputStream_iconv(); diff --git a/src/vmime/charsetConverter_icu.cpp b/src/vmime/charsetConverter_icu.cpp index a41a0842..a7dd474c 100644 --- a/src/vmime/charsetConverter_icu.cpp +++ b/src/vmime/charsetConverter_icu.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,8 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -extern "C" -{ +extern "C" { + #ifndef VMIME_BUILDING_DOC #include @@ -48,59 +48,75 @@ extern "C" #include -namespace vmime -{ +namespace vmime { // static -shared_ptr charsetConverter::createGenericConverter - (const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ +shared_ptr charsetConverter::createGenericConverter( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + return make_shared (source, dest, opts); } -charsetConverter_icu::charsetConverter_icu - (const charset& source, const charset& dest, const charsetConverterOptions& opts) - : m_from(NULL), m_to(NULL), m_source(source), m_dest(dest), m_options(opts) -{ +charsetConverter_icu::charsetConverter_icu( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) + : m_from(NULL), + m_to(NULL), + m_source(source), + m_dest(dest), + m_options(opts) { + UErrorCode err = U_ZERO_ERROR; m_from = ucnv_open(source.getName().c_str(), &err); - if (!U_SUCCESS(err)) - { - throw exceptions::charset_conv_error - ("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + "."); + if (!U_SUCCESS(err)) { + + throw exceptions::charset_conv_error( + "Cannot initialize ICU converter for source charset '" + source.getName() + + "' (error code: " + u_errorName(err) + "." + ); } m_to = ucnv_open(dest.getName().c_str(), &err); - if (!U_SUCCESS(err)) - { - throw exceptions::charset_conv_error - ("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + "."); + if (!U_SUCCESS(err)) { + + throw exceptions::charset_conv_error( + "Cannot initialize ICU converter for destination charset '" + dest.getName() + + "' (error code: " + u_errorName(err) + "." + ); } } -charsetConverter_icu::~charsetConverter_icu() -{ +charsetConverter_icu::~charsetConverter_icu() { + if (m_from) ucnv_close(m_from); if (m_to) ucnv_close(m_to); } -void charsetConverter_icu::convert - (utility::inputStream& in, utility::outputStream& out, status* st) -{ +void charsetConverter_icu::convert( + utility::inputStream& in, + utility::outputStream& out, + status* st +) { + UErrorCode err = U_ZERO_ERROR; ucnv_reset(m_from); ucnv_reset(m_to); - if (st) + if (st) { new (st) status(); + } // From buffers byte_t cpInBuffer[16]; // stream data put here @@ -113,34 +129,39 @@ void charsetConverter_icu::convert std::vector cpOutBuffer(cpOutBufferSz); // Tell ICU what to do when encountering an illegal byte sequence - if (m_options.silentlyReplaceInvalidSequences) - { + if (m_options.silentlyReplaceInvalidSequences) { + // Set replacement chars for when converting from Unicode to codepage icu::UnicodeString substString(m_options.invalidSequence.c_str()); ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting substitution string."); - } - else - { + } + + } else { + // Tell ICU top stop (and return an error) on illegal byte sequences - ucnv_setToUCallBack - (m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); + ucnv_setToUCallBack( + m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err + ); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback."); + } - ucnv_setFromUCallBack - (m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); + ucnv_setFromUCallBack( + m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err + ); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback."); + } } // Input data available - while (!in.eof()) - { + while (!in.eof()) { + // Read input data into buffer size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer)); @@ -153,30 +174,36 @@ void charsetConverter_icu::convert UErrorCode toErr; // Loop until all source has been processed - do - { + do { + // Set up target pointers UChar* target = &uOutBuffer[0]; UChar* targetLimit = &target[0] + outSize; toErr = U_ZERO_ERROR; - ucnv_toUnicode(m_from, &target, targetLimit, - &source, sourceLimit, NULL, flush, &toErr); - if (st) + ucnv_toUnicode( + m_from, &target, targetLimit, + &source, sourceLimit, NULL, flush, &toErr + ); + + if (st) { st->inputBytesRead += (source - reinterpret_cast (&cpInBuffer[0])); + } + + if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) { - if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) - { if (toErr == U_INVALID_CHAR_FOUND || toErr == U_TRUNCATED_CHAR_FOUND || - toErr == U_ILLEGAL_CHAR_FOUND) - { + toErr == U_ILLEGAL_CHAR_FOUND) { + // Error will be thrown later (*) - } - else - { - throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName()); + + } else { + + throw exceptions::charset_conv_error( + "[ICU] Error converting to Unicode from " + m_source.getName() + ); } } @@ -187,19 +214,21 @@ void charsetConverter_icu::convert UErrorCode fromErr; // Loop until converted chars are fully written - do - { + do { + char* cpTarget = &cpOutBuffer[0]; const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz; fromErr = U_ZERO_ERROR; // Write converted bytes (Unicode) to destination codepage - ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit, - &uSource, uSourceLimit, NULL, flush, &fromErr); + ucnv_fromUnicode( + m_to, &cpTarget, cpTargetLimit, + &uSource, uSourceLimit, NULL, flush, &fromErr + ); + + if (st) { - if (st) - { // Decrement input bytes count by the number of input bytes in error char errBytes[16]; int8_t errBytesLen = sizeof(errBytes); @@ -214,22 +243,24 @@ void charsetConverter_icu::convert // (*) If an error occurred while converting from input charset, throw it now if (toErr == U_INVALID_CHAR_FOUND || toErr == U_TRUNCATED_CHAR_FOUND || - toErr == U_ILLEGAL_CHAR_FOUND) - { + toErr == U_ILLEGAL_CHAR_FOUND) { + throw exceptions::illegal_byte_sequence_for_charset(); } - if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) - { + if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) { + if (fromErr == U_INVALID_CHAR_FOUND || fromErr == U_TRUNCATED_CHAR_FOUND || - fromErr == U_ILLEGAL_CHAR_FOUND) - { + fromErr == U_ILLEGAL_CHAR_FOUND) { + throw exceptions::illegal_byte_sequence_for_charset(); - } - else - { - throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName()); + + } else { + + throw exceptions::charset_conv_error( + "[ICU] Error converting from Unicode to " + m_dest.getName() + ); } } @@ -243,10 +274,11 @@ void charsetConverter_icu::convert } -void charsetConverter_icu::convert(const string& in, string& out, status* st) -{ - if (st) +void charsetConverter_icu::convert(const string& in, string& out, status* st) { + + if (st) { new (st) status(); + } out.clear(); @@ -260,9 +292,11 @@ void charsetConverter_icu::convert(const string& in, string& out, status* st) shared_ptr - charsetConverter_icu::getFilteredOutputStream - (utility::outputStream& os, const charsetConverterOptions& opts) -{ + charsetConverter_icu::getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts + ) { + return make_shared (m_source, m_dest, &os, opts); } @@ -273,75 +307,94 @@ shared_ptr namespace utility { -charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu - (const charset& source, const charset& dest, outputStream* os, - const charsetConverterOptions& opts) - : m_from(NULL), m_to(NULL), m_sourceCharset(source), - m_destCharset(dest), m_stream(*os), m_options(opts) -{ +charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu( + const charset& source, + const charset& dest, + outputStream* os, + const charsetConverterOptions& opts +) + : m_from(NULL), + m_to(NULL), + m_sourceCharset(source), + m_destCharset(dest), + m_stream(*os), + m_options(opts) { + UErrorCode err = U_ZERO_ERROR; m_from = ucnv_open(source.getName().c_str(), &err); - if (!U_SUCCESS(err)) - { - throw exceptions::charset_conv_error - ("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + "."); + if (!U_SUCCESS(err)) { + + throw exceptions::charset_conv_error( + "Cannot initialize ICU converter for source charset '" + source.getName() + + "' (error code: " + u_errorName(err) + "." + ); } m_to = ucnv_open(dest.getName().c_str(), &err); - if (!U_SUCCESS(err)) - { - throw exceptions::charset_conv_error - ("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + "."); + if (!U_SUCCESS(err)) { + + throw exceptions::charset_conv_error( + "Cannot initialize ICU converter for destination charset '" + dest.getName() + + "' (error code: " + u_errorName(err) + "." + ); } // Tell ICU what to do when encountering an illegal byte sequence - if (m_options.silentlyReplaceInvalidSequences) - { + if (m_options.silentlyReplaceInvalidSequences) { + // Set replacement chars for when converting from Unicode to codepage icu::UnicodeString substString(m_options.invalidSequence.c_str()); ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting substitution string."); - } - else - { + } + + } else { + // Tell ICU top stop (and return an error) on illegal byte sequences - ucnv_setToUCallBack - (m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); + ucnv_setToUCallBack( + m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err + ); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback."); + } - ucnv_setFromUCallBack - (m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err); + ucnv_setFromUCallBack( + m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err + ); - if (U_FAILURE(err)) + if (U_FAILURE(err)) { throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback."); + } } } -charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu() -{ +charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu() { + if (m_from) ucnv_close(m_from); if (m_to) ucnv_close(m_to); } -outputStream& charsetFilteredOutputStream_icu::getNextOutputStream() -{ +outputStream& charsetFilteredOutputStream_icu::getNextOutputStream() { + return m_stream; } -void charsetFilteredOutputStream_icu::writeImpl - (const byte_t* const data, const size_t count) -{ - if (m_from == NULL || m_to == NULL) +void charsetFilteredOutputStream_icu::writeImpl( + const byte_t* const data, + const size_t count +) { + + if (!m_from || !m_to) { throw exceptions::charset_conv_error("Cannot initialize converters."); + } // Allocate buffer for Unicode chars const size_t uniSize = ucnv_getMinCharSize(m_from) * count * sizeof(UChar); @@ -353,29 +406,32 @@ void charsetFilteredOutputStream_icu::writeImpl const char* uniSource = reinterpret_cast (data); const char* uniSourceLimit = uniSource + count; - do - { + do { + // Convert from source charset to Unicode UChar* uniTarget = &uniBuffer[0]; UChar* uniTargetLimit = &uniBuffer[0] + uniSize; toErr = U_ZERO_ERROR; - ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit, - &uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr); + ucnv_toUnicode( + m_from, &uniTarget, uniTargetLimit, + &uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr + ); + + if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) { - if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) - { if (toErr == U_INVALID_CHAR_FOUND || toErr == U_TRUNCATED_CHAR_FOUND || - toErr == U_ILLEGAL_CHAR_FOUND) - { + toErr == U_ILLEGAL_CHAR_FOUND) { + throw exceptions::illegal_byte_sequence_for_charset(); - } - else - { - throw exceptions::charset_conv_error - ("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."); + + } else { + + throw exceptions::charset_conv_error( + "[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'." + ); } } @@ -391,28 +447,31 @@ void charsetFilteredOutputStream_icu::writeImpl const UChar* cpSource = &uniBuffer[0]; const UChar* cpSourceLimit = &uniBuffer[0] + uniLength; - do - { + do { + char* cpTarget = &cpBuffer[0]; char* cpTargetLimit = &cpBuffer[0] + cpSize; fromErr = U_ZERO_ERROR; - ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit, - &cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr); + ucnv_fromUnicode( + m_to, &cpTarget, cpTargetLimit, + &cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr + ); + + if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) { - if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) - { if (fromErr == U_INVALID_CHAR_FOUND || fromErr == U_TRUNCATED_CHAR_FOUND || - fromErr == U_ILLEGAL_CHAR_FOUND) - { + fromErr == U_ILLEGAL_CHAR_FOUND) { + throw exceptions::illegal_byte_sequence_for_charset(); - } - else - { - throw exceptions::charset_conv_error - ("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."); + + } else { + + throw exceptions::charset_conv_error( + "[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'." + ); } } @@ -427,10 +486,11 @@ void charsetFilteredOutputStream_icu::writeImpl } -void charsetFilteredOutputStream_icu::flush() -{ - if (m_from == NULL || m_to == NULL) +void charsetFilteredOutputStream_icu::flush() { + + if (!m_from || !m_to) { throw exceptions::charset_conv_error("Cannot initialize converters."); + } // Allocate buffer for Unicode chars const size_t uniSize = ucnv_getMinCharSize(m_from) * 1024 * sizeof(UChar); @@ -442,21 +502,24 @@ void charsetFilteredOutputStream_icu::flush() const char* uniSource = 0; const char* uniSourceLimit = 0; - do - { + do { + // Convert from source charset to Unicode UChar* uniTarget = &uniBuffer[0]; UChar* uniTargetLimit = &uniBuffer[0] + uniSize; toErr = U_ZERO_ERROR; - ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit, - &uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr); + ucnv_toUnicode( + m_from, &uniTarget, uniTargetLimit, + &uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr + ); - if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) - { - throw exceptions::charset_conv_error - ("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."); + if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) { + + throw exceptions::charset_conv_error( + "[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'." + ); } const size_t uniLength = uniTarget - &uniBuffer[0]; @@ -471,20 +534,23 @@ void charsetFilteredOutputStream_icu::flush() const UChar* cpSource = &uniBuffer[0]; const UChar* cpSourceLimit = &uniBuffer[0] + uniLength; - do - { + do { + char* cpTarget = &cpBuffer[0]; char* cpTargetLimit = &cpBuffer[0] + cpSize; fromErr = U_ZERO_ERROR; - ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit, - &cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr); + ucnv_fromUnicode( + m_to, &cpTarget, cpTargetLimit, + &cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr + ); - if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) - { - throw exceptions::charset_conv_error - ("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."); + if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) { + + throw exceptions::charset_conv_error( + "[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'." + ); } const size_t cpLength = cpTarget - &cpBuffer[0]; diff --git a/src/vmime/charsetConverter_icu.hpp b/src/vmime/charsetConverter_icu.hpp index 9b03f643..cf5eb6bc 100644 --- a/src/vmime/charsetConverter_icu.hpp +++ b/src/vmime/charsetConverter_icu.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,15 +37,13 @@ struct UConverter; -namespace vmime -{ +namespace vmime { /** A generic charset converter which uses ICU library. */ +class charsetConverter_icu : public charsetConverter { -class charsetConverter_icu : public charsetConverter -{ public: /** Construct and initialize an ICU charset converter. @@ -54,17 +52,21 @@ public: * @param dest output charset * @param opts conversion options */ - charsetConverter_icu(const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetConverter_icu( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); ~charsetConverter_icu(); void convert(const string& in, string& out, status* st = NULL); void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL); - shared_ptr getFilteredOutputStream - (utility::outputStream& os, - const charsetConverterOptions& opts = charsetConverterOptions()); + shared_ptr getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts = charsetConverterOptions() + ); private: @@ -81,8 +83,8 @@ private: namespace utility { -class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream -{ +class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream { + public: /** Construct a new filter for the specified output stream. @@ -92,9 +94,12 @@ public: * @param os stream into which write filtered data * @param opts conversion options */ - charsetFilteredOutputStream_icu - (const charset& source, const charset& dest, outputStream* os, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetFilteredOutputStream_icu( + const charset& source, + const charset& dest, + outputStream* os, + const charsetConverterOptions& opts = charsetConverterOptions() + ); ~charsetFilteredOutputStream_icu(); diff --git a/src/vmime/charsetConverter_idna.cpp b/src/vmime/charsetConverter_idna.cpp index b9e79842..eb8764f5 100644 --- a/src/vmime/charsetConverter_idna.cpp +++ b/src/vmime/charsetConverter_idna.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,8 +30,7 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -extern "C" -{ +extern "C" { #include "contrib/punycode/punycode.h" #include "contrib/punycode/punycode.c" @@ -41,26 +40,31 @@ extern "C" #include "contrib/utf8/utf8.h" -namespace vmime -{ +namespace vmime { -charsetConverter_idna::charsetConverter_idna - (const charset& source, const charset& dest, const charsetConverterOptions& opts) - : m_source(source), m_dest(dest), m_options(opts) -{ +charsetConverter_idna::charsetConverter_idna( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) + : m_source(source), + m_dest(dest), + m_options(opts) { + } -charsetConverter_idna::~charsetConverter_idna() -{ +charsetConverter_idna::~charsetConverter_idna() { + } -void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st) -{ - if (st) +void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st) { + + if (st) { new (st) status(); + } // IDNA should be used for short strings, so it does not matter if we // do not work directly on the stream @@ -75,19 +79,19 @@ void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStr } -void charsetConverter_idna::convert(const string& in, string& out, status* st) -{ - if (st) +void charsetConverter_idna::convert(const string& in, string& out, status* st) { + + if (st) { new (st) status(); + } out.clear(); - if (m_dest == "idna") - { - if (utility::stringUtils::is7bit(in)) - { - if (st) - { + if (m_dest == "idna") { + + if (utility::stringUtils::is7bit(in)) { + + if (st) { st->inputBytesRead = in.length(); st->outputBytesWritten = in.length(); } @@ -106,41 +110,42 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st) std::vector unichars; unichars.reserve(inUTF8.length()); - while (ch < end) - { + while (ch < end) { const utf8::uint32_t uc = utf8::unchecked::next(ch); unichars.push_back(uc); } - if (st) + if (st) { st->inputBytesRead = in.length(); + } punycode_uint inputLen = static_cast (unichars.size()); std::vector output(inUTF8.length() * 2); punycode_uint outputLen = static_cast (output.size()); - const punycode_status status = punycode_encode - (inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]); + const punycode_status status = punycode_encode( + inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0] + ); + + if (status == punycode_success) { - if (status == punycode_success) - { out = string("xn--") + string(output.begin(), output.begin() + outputLen); - if (st) + if (st) { st->outputBytesWritten = out.length(); - } - else - { + } + + } else { + // TODO } - } - else if (m_source == "idna") - { - if (in.length() < 5 || in.substr(0, 4) != "xn--") - { - if (st) - { + + } else if (m_source == "idna") { + + if (in.length() < 5 || in.substr(0, 4) != "xn--") { + + if (st) { st->inputBytesRead = in.length(); st->outputBytesWritten = in.length(); } @@ -155,31 +160,34 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st) std::vector output(in.length() - 4); punycode_uint outputLen = static_cast (output.size()); - const punycode_status status = punycode_decode - (inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL); + const punycode_status status = punycode_decode( + inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL + ); - if (st) + if (st) { st->inputBytesRead = in.length(); + } + + if (status == punycode_success) { - if (status == punycode_success) - { std::vector outUTF8Bytes(outputLen * 4); char* p = &outUTF8Bytes[0]; for (std::vector ::const_iterator it = output.begin() ; - it != output.begin() + outputLen ; ++it) - { + it != output.begin() + outputLen ; ++it) { + p = utf8::unchecked::append(*it, p); } string outUTF8(&outUTF8Bytes[0], p); charset::convert(outUTF8, out, vmime::charsets::UTF_8, m_dest); - if (st) + if (st) { st->outputBytesWritten = out.length(); - } - else - { + } + + } else { + // TODO } } @@ -187,9 +195,12 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st) shared_ptr - charsetConverter_idna::getFilteredOutputStream - (utility::outputStream& /* os */, const charsetConverterOptions& /* opts */) -{ + charsetConverter_idna::getFilteredOutputStream( + utility::outputStream& /* os */, + const charsetConverterOptions& /* opts */ + ) { + + // Not supported return null; } diff --git a/src/vmime/charsetConverter_idna.hpp b/src/vmime/charsetConverter_idna.hpp index 06ffbcdd..aaf547d0 100644 --- a/src/vmime/charsetConverter_idna.hpp +++ b/src/vmime/charsetConverter_idna.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/charsetConverter.hpp" -namespace vmime -{ +namespace vmime { /** A charset converter which can convert to and from Punycode (for IDNA). */ +class charsetConverter_idna : public charsetConverter { -class charsetConverter_idna : public charsetConverter -{ public: /** Construct and initialize an IDNA charset converter. @@ -45,17 +43,21 @@ public: * @param dest output charset * @param opts conversion options */ - charsetConverter_idna(const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetConverter_idna( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); ~charsetConverter_idna(); void convert(const string& in, string& out, status* st = NULL); void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL); - shared_ptr getFilteredOutputStream - (utility::outputStream& os, - const charsetConverterOptions& opts = charsetConverterOptions()); + shared_ptr getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts = charsetConverterOptions() + ); private: diff --git a/src/vmime/charsetConverter_win.cpp b/src/vmime/charsetConverter_win.cpp index 2c65f5fd..eab18291 100644 --- a/src/vmime/charsetConverter_win.cpp +++ b/src/vmime/charsetConverter_win.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,37 +49,46 @@ #define CP_UNICODE 1200 -namespace vmime -{ +namespace vmime { // static -shared_ptr charsetConverter::createGenericConverter - (const charset& source, const charset& dest, - const charsetConverterOptions& opts) -{ +shared_ptr charsetConverter::createGenericConverter( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) { + return make_shared (source, dest, opts); } -charsetConverter_win::charsetConverter_win - (const charset& source, const charset& dest, const charsetConverterOptions& opts) - : m_source(source), m_dest(dest), m_options(opts) -{ +charsetConverter_win::charsetConverter_win( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts +) + : m_source(source), + m_dest(dest), + m_options(opts) { + } -void charsetConverter_win::convert - (utility::inputStream& in, utility::outputStream& out, status* st) -{ - if (st) +void charsetConverter_win::convert( + utility::inputStream& in, + utility::outputStream& out, + status* st +) { + + if (st) { new (st) status(); + } byte_t buffer[32768]; string inStr, outStr; - while (!in.eof()) - { + while (!in.eof()) { const size_t len = in.read(buffer, sizeof(buffer)); utility::stringUtils::appendBytesToString(inStr, buffer, len); } @@ -90,10 +99,11 @@ void charsetConverter_win::convert } -void charsetConverter_win::convert(const string& in, string& out, status* st) -{ - if (st) +void charsetConverter_win::convert(const string& in, string& out, status* st) { + + if (st) { new (st) status(); + } const int sourceCodePage = getCodePage(m_source.getName().c_str()); const int destCodePage = getCodePage(m_dest.getName().c_str()); @@ -103,69 +113,77 @@ void charsetConverter_win::convert(const string& in, string& out, status* st) const WCHAR* unicodePtr = NULL; size_t unicodeLen = 0; - if (sourceCodePage == CP_UNICODE) - { + if (sourceCodePage == CP_UNICODE) { + unicodePtr = reinterpret_cast (in.c_str()); unicodeLen = in.length() / 2; - } - else - { - const size_t bufferSize = MultiByteToWideChar - (sourceCodePage, 0, in.c_str(), static_cast (in.length()), - NULL, 0) * sizeof(WCHAR); // in wide characters + + } else { + + const size_t bufferSize = MultiByteToWideChar( + sourceCodePage, 0, in.c_str(), static_cast (in.length()), NULL, 0 + ) * sizeof(WCHAR); // in wide characters unicodeBuffer.resize(bufferSize); DWORD flags = 0; - if (!m_options.silentlyReplaceInvalidSequences) + if (!m_options.silentlyReplaceInvalidSequences) { flags |= MB_ERR_INVALID_CHARS; + } unicodePtr = reinterpret_cast (&unicodeBuffer[0]); - unicodeLen = MultiByteToWideChar - (sourceCodePage, 0, in.c_str(), static_cast (in.length()), - reinterpret_cast (&unicodeBuffer[0]), static_cast (bufferSize)); + unicodeLen = MultiByteToWideChar( + sourceCodePage, 0, in.c_str(), static_cast (in.length()), + reinterpret_cast (&unicodeBuffer[0]), static_cast (bufferSize) + ); + + if (unicodeLen == 0) { + + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { - if (unicodeLen == 0) - { - if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) - { throw exceptions::illegal_byte_sequence_for_charset(); - } - else - { - throw exceptions::charset_conv_error("MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName()); + + } else { + + throw exceptions::charset_conv_error( + "MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName() + ); } } } // Convert from Unicode to destination charset - if (destCodePage == CP_UNICODE) - { + if (destCodePage == CP_UNICODE) { + out.assign(reinterpret_cast (unicodePtr), unicodeLen * 2); - } - else - { - const size_t bufferSize = WideCharToMultiByte - (destCodePage, 0, unicodePtr, static_cast (unicodeLen), - NULL, 0, 0, NULL); // in multibyte characters + + } else { + + const size_t bufferSize = WideCharToMultiByte( + destCodePage, 0, unicodePtr, static_cast (unicodeLen), + NULL, 0, 0, NULL + ); // in multibyte characters std::vector buffer; buffer.resize(bufferSize); - const size_t len = WideCharToMultiByte - (destCodePage, 0, unicodePtr, static_cast (unicodeLen), - &buffer[0], static_cast (bufferSize), 0, NULL); + const size_t len = WideCharToMultiByte( + destCodePage, 0, unicodePtr, static_cast (unicodeLen), + &buffer[0], static_cast (bufferSize), 0, NULL + ); + + if (len == 0) { + + if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { - if (len == 0) - { - if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) - { throw exceptions::illegal_byte_sequence_for_charset(); - } - else - { - throw exceptions::charset_conv_error("WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName()); + + } else { + + throw exceptions::charset_conv_error( + "WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName() + ); } } @@ -175,15 +193,16 @@ void charsetConverter_win::convert(const string& in, string& out, status* st) // static -int charsetConverter_win::getCodePage(const char* name) -{ - if (_stricmp(name, charsets::UTF_16) == 0) // wchar_t is UTF-16 on Windows +int charsetConverter_win::getCodePage(const char* name) { + + if (_stricmp(name, charsets::UTF_16) == 0) { // wchar_t is UTF-16 on Windows return CP_UNICODE; + } // "cp1252" --> return 1252 if ((name[0] == 'c' || name[0] == 'C') && - (name[1] == 'p' || name[1] == 'P')) - { + (name[1] == 'p' || name[1] == 'P')) { + return atoi(name + 2); } @@ -192,9 +211,11 @@ int charsetConverter_win::getCodePage(const char* name) shared_ptr - charsetConverter_win::getFilteredOutputStream - (utility::outputStream& /* os */, const charsetConverterOptions& /* opts */) -{ + charsetConverter_win::getFilteredOutputStream( + utility::outputStream& /* os */, + const charsetConverterOptions& /* opts */ + ) { + // TODO: implement me! return null; } diff --git a/src/vmime/charsetConverter_win.hpp b/src/vmime/charsetConverter_win.hpp index 7cf38104..d20970b9 100644 --- a/src/vmime/charsetConverter_win.hpp +++ b/src/vmime/charsetConverter_win.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,7 @@ #include "vmime/charsetConverter.hpp" -namespace vmime -{ +namespace vmime { /** A generic charset converter which uses Windows MultiByteToWideChar @@ -49,9 +48,8 @@ namespace vmime * * Also, "status" is not supported by this converter for the same reason. */ +class charsetConverter_win : public charsetConverter { -class charsetConverter_win : public charsetConverter -{ public: /** Construct and initialize a Windows charset converter. @@ -60,14 +58,19 @@ public: * @param dest output charset * @param opts conversion options */ - charsetConverter_win(const charset& source, const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()); + charsetConverter_win( + const charset& source, + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ); void convert(const string& in, string& out, status* st); void convert(utility::inputStream& in, utility::outputStream& out, status* st); - shared_ptr - getFilteredOutputStream(utility::outputStream& os, const charsetConverterOptions& opts); + shared_ptr getFilteredOutputStream( + utility::outputStream& os, + const charsetConverterOptions& opts + ); private: diff --git a/src/vmime/component.cpp b/src/vmime/component.cpp index 342d087b..7adf8f71 100644 --- a/src/vmime/component.cpp +++ b/src/vmime/component.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,48 +31,54 @@ #include -namespace vmime -{ +namespace vmime { component::component() - : m_parsedOffset(0), m_parsedLength(0) -{ + : m_parsedOffset(0), m_parsedLength(0) { + } -component::~component() -{ +component::~component() { + } -void component::parse - (const shared_ptr & inputStream, const size_t length) -{ +void component::parse( + const shared_ptr & inputStream, + const size_t length +) { + parse(inputStream, 0, length, NULL); } -void component::parse - (const shared_ptr & inputStream, const size_t position, - const size_t end, size_t* newPosition) -{ +void component::parse( + const shared_ptr & inputStream, + const size_t position, + const size_t end, + size_t* newPosition) { + parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition); } -void component::parse - (const parsingContext& ctx, - const shared_ptr & inputStream, const size_t position, - const size_t end, size_t* newPosition) -{ +void component::parse( + const parsingContext& ctx, + const shared_ptr & inputStream, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_parsedOffset = m_parsedLength = 0; shared_ptr seekableStream = dynamicCast (inputStream); - if (seekableStream == NULL || end == 0) - { + if (!seekableStream || end == 0) { + // Read the whole stream into a buffer std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); @@ -81,9 +87,9 @@ void component::parse const string buffer = oss.str(); parseImpl(ctx, buffer, 0, buffer.length(), NULL); - } - else - { + + } else { + shared_ptr parser = make_shared (seekableStream); @@ -92,79 +98,95 @@ void component::parse } -void component::parse(const string& buffer) -{ +void component::parse(const string& buffer) { + m_parsedOffset = m_parsedLength = 0; parseImpl(parsingContext::getDefaultContext(), buffer, 0, buffer.length(), NULL); } -void component::parse(const parsingContext& ctx, const string& buffer) -{ +void component::parse(const parsingContext& ctx, const string& buffer) { + m_parsedOffset = m_parsedLength = 0; parseImpl(ctx, buffer, 0, buffer.length(), NULL); } -void component::parse - (const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void component::parse( + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_parsedOffset = m_parsedLength = 0; parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition); } -void component::parse - (const parsingContext& ctx, - const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void component::parse( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, size_t* newPosition +) { + m_parsedOffset = m_parsedLength = 0; parseImpl(ctx, buffer, position, end, newPosition); } -void component::offsetParsedBounds(const size_t offset) -{ +void component::offsetParsedBounds(const size_t offset) { + // Offset parsed bounds of this component - if (m_parsedLength != 0) + if (m_parsedLength != 0) { m_parsedOffset += offset; + } // Offset parsed bounds of our children std::vector > children = getChildComponents(); - for (size_t i = 0, n = children.size() ; i < n ; ++i) + for (size_t i = 0, n = children.size() ; i < n ; ++i) { children[i]->offsetParsedBounds(offset); + } } -void component::parseImpl - (const parsingContext& ctx, const shared_ptr & parser, - const size_t position, const size_t end, size_t* newPosition) -{ +void component::parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition +) { + // This is the default implementation for parsing from an input stream: // actually, we extract the substring and use the "parse from string" implementation const string buffer = parser->extract(position, end); parseImpl(ctx, buffer, 0, buffer.length(), newPosition); // Recursivey offset parsed bounds on children - if (position != 0) + if (position != 0) { offsetParsedBounds(position); + } - if (newPosition != NULL) + if (newPosition) { *newPosition += position; + } } -void component::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void component::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition) { + // This is the default implementation for parsing from a string: // actually, we encapsulate the string buffer in an input stream, then use // the "parse from input stream" implementation @@ -178,9 +200,11 @@ void component::parseImpl } -const string component::generate - (const size_t maxLineLength, const size_t curLinePos) const -{ +const string component::generate( + const size_t maxLineLength, + const size_t curLinePos +) const { + std::ostringstream oss; utility::outputStreamAdapter adapter(oss); @@ -189,56 +213,63 @@ const string component::generate generateImpl(ctx, adapter, curLinePos, NULL); - return (oss.str()); + return oss.str(); } -void component::generate - (utility::outputStream& os, const size_t curLinePos, size_t* newLinePos) const -{ - generateImpl(generationContext::getDefaultContext(), - os, curLinePos, newLinePos); +void component::generate( + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + + generateImpl(generationContext::getDefaultContext(), os, curLinePos, newLinePos); } -void component::generate - (const generationContext& ctx, utility::outputStream& outputStream, - const size_t curLinePos, size_t* newLinePos) const -{ +void component::generate( + const generationContext& ctx, + utility::outputStream& outputStream, + const size_t curLinePos, + size_t* newLinePos +) const { + generateImpl(ctx, outputStream, curLinePos, newLinePos); } -size_t component::getParsedOffset() const -{ - return (m_parsedOffset); +size_t component::getParsedOffset() const { + + return m_parsedOffset; } -size_t component::getParsedLength() const -{ - return (m_parsedLength); +size_t component::getParsedLength() const { + + return m_parsedLength; } -void component::setParsedBounds(const size_t start, const size_t end) -{ +void component::setParsedBounds(const size_t start, const size_t end) { + m_parsedOffset = start; m_parsedLength = end - start; } -size_t component::getGeneratedSize(const generationContext& ctx) -{ +size_t component::getGeneratedSize(const generationContext& ctx) { + std::vector > children = getChildComponents(); size_t totalSize = 0; - for (std::vector >::iterator it = children.begin() ; it != children.end() ; ++it) + for (std::vector >::iterator it = children.begin() ; + it != children.end() ; ++it) { + totalSize += (*it)->getGeneratedSize(ctx); + } return totalSize; } } // vmime - diff --git a/src/vmime/component.hpp b/src/vmime/component.hpp index 6c360746..91164c30 100644 --- a/src/vmime/component.hpp +++ b/src/vmime/component.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,16 +34,14 @@ #include "vmime/parsingContext.hpp" -namespace vmime -{ +namespace vmime { /** This abstract class is the base class for all the components of a message. * It defines methods for parsing and generating a component. */ +class VMIME_EXPORT component : public object { -class VMIME_EXPORT component : public object -{ public: component(); @@ -80,11 +78,12 @@ public: * @param end end position in the input buffer * @param newPosition will receive the new position in the input buffer */ - void parse - (const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parse( + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); /** Parse RFC-822/MIME data for this component. * @@ -94,12 +93,13 @@ public: * @param end end position in the input buffer * @param newPosition will receive the new position in the input buffer */ - void parse - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parse( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); /** Parse RFC-822/MIME data for this component. If stream is not seekable, * or if end position is not specified, entire contents of the stream will @@ -111,11 +111,12 @@ public: * @param end end position in the input stream * @param newPosition will receive the new position in the input stream */ - void parse - (const shared_ptr & inputStream, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parse( + const shared_ptr & inputStream, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); /** Parse RFC-822/MIME data for this component. If stream is not seekable, * or if end position is not specified, entire contents of the stream will @@ -127,12 +128,13 @@ public: * @param end end position in the input stream * @param newPosition will receive the new position in the input stream */ - void parse - (const parsingContext& ctx, - const shared_ptr & inputStream, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parse( + const parsingContext& ctx, + const shared_ptr & inputStream, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); /** Generate RFC-2822/MIME data for this component. * @@ -142,9 +144,10 @@ public: * @param curLinePos length of the current line in the output buffer * @return generated data */ - virtual const string generate - (const size_t maxLineLength = lineLengthLimits::infinite, - const size_t curLinePos = 0) const; + virtual const string generate( + const size_t maxLineLength = lineLengthLimits::infinite, + const size_t curLinePos = 0 + ) const; /** Generate RFC-2822/MIME data for this component, using the default generation context. * @@ -152,10 +155,11 @@ public: * @param curLinePos length of the current line in the output buffer * @param newLinePos will receive the new line position (length of the last line written) */ - virtual void generate - (utility::outputStream& outputStream, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + virtual void generate( + utility::outputStream& outputStream, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; /** Generate RFC-2822/MIME data for this component, using the default generation context. * @@ -164,11 +168,12 @@ public: * @param curLinePos length of the current line in the output buffer * @param newLinePos will receive the new line position (length of the last line written) */ - virtual void generate - (const generationContext& ctx, - utility::outputStream& outputStream, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + virtual void generate( + const generationContext& ctx, + utility::outputStream& outputStream, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; /** Clone this component. * @@ -222,25 +227,28 @@ protected: void setParsedBounds(const size_t start, const size_t end); // AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class - virtual void parseImpl - (const parsingContext& ctx, - const shared_ptr & parser, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + virtual void parseImpl( + const parsingContext& ctx, + const shared_ptr & parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - virtual void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + virtual void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - virtual void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const = 0; + virtual void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const = 0; private: diff --git a/src/vmime/constants.cpp b/src/vmime/constants.cpp index 3b0a54c0..2b242885 100644 --- a/src/vmime/constants.cpp +++ b/src/vmime/constants.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,13 +24,12 @@ #include "vmime/constants.hpp" -namespace vmime -{ +namespace vmime { // Media Types -namespace mediaTypes -{ +namespace mediaTypes { + // Types const char* const TEXT = "text"; const char* const MULTIPART = "multipart"; @@ -72,8 +71,8 @@ namespace mediaTypes // Encoding types -namespace encodingTypes -{ +namespace encodingTypes { + const char* const SEVEN_BIT = "7bit"; const char* const EIGHT_BIT = "8bit"; const char* const BASE64 = "base64"; @@ -84,16 +83,16 @@ namespace encodingTypes // Content disposition types -namespace contentDispositionTypes -{ +namespace contentDispositionTypes { + const char* const INLINE = "inline"; const char* const ATTACHMENT = "attachment"; } // Charsets -namespace charsets -{ +namespace charsets { + const char* const ISO8859_1 = "iso-8859-1"; const char* const ISO8859_2 = "iso-8859-2"; const char* const ISO8859_3 = "iso-8859-3"; @@ -159,8 +158,8 @@ namespace charsets // Fields -namespace fields -{ +namespace fields { + const char* const RECEIVED = "Received"; const char* const FROM = "From"; const char* const SENDER = "Sender"; @@ -204,32 +203,32 @@ namespace fields // Constants for disposition action modes (RFC-3978). -namespace dispositionActionModes -{ +namespace dispositionActionModes { + const char* const MANUAL = "manual"; const char* const AUTOMATIC = "automatic"; } // Constants for disposition sending modes (RFC-3798). -namespace dispositionSendingModes -{ +namespace dispositionSendingModes { + const char* const SENT_MANUALLY = "MDN-sent-manually"; const char* const SENT_AUTOMATICALLY ="MDN-sent-automatically"; } // Constants for disposition types (RFC-3798). -namespace dispositionTypes -{ +namespace dispositionTypes { + const char* const DISPLAYED = "displayed"; const char* const DELETED = "deleted"; } // Constants for disposition modifiers (RFC-3798). -namespace dispositionModifiers -{ +namespace dispositionModifiers { + const char* const ERROR = "error"; } diff --git a/src/vmime/constants.hpp b/src/vmime/constants.hpp index 8e6e3f83..17fbd3ad 100644 --- a/src/vmime/constants.hpp +++ b/src/vmime/constants.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free SOFTWARE; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,11 +37,11 @@ #endif -namespace vmime -{ +namespace vmime { + /** Constants for media types. */ - namespace mediaTypes - { + namespace mediaTypes { + // Types extern VMIME_EXPORT const char* const TEXT; extern VMIME_EXPORT const char* const MULTIPART; @@ -83,8 +83,8 @@ namespace vmime /** Constants for encoding types. */ - namespace encodingTypes - { + namespace encodingTypes { + extern VMIME_EXPORT const char* const SEVEN_BIT; extern VMIME_EXPORT const char* const EIGHT_BIT; extern VMIME_EXPORT const char* const BASE64; @@ -95,16 +95,16 @@ namespace vmime /** Constants for content disposition types (RFC-2183). */ - namespace contentDispositionTypes - { + namespace contentDispositionTypes { + extern VMIME_EXPORT const char* const INLINE; extern VMIME_EXPORT const char* const ATTACHMENT; } /** Constants for charsets. */ - namespace charsets - { + namespace charsets { + extern VMIME_EXPORT const char* const ISO8859_1; extern VMIME_EXPORT const char* const ISO8859_2; extern VMIME_EXPORT const char* const ISO8859_3; @@ -169,8 +169,8 @@ namespace vmime } /** Constants for standard field names. */ - namespace fields - { + namespace fields { + extern VMIME_EXPORT const char* const RECEIVED; extern VMIME_EXPORT const char* const FROM; extern VMIME_EXPORT const char* const SENDER; @@ -213,8 +213,8 @@ namespace vmime } /** Constants for disposition action modes (RFC-3978). */ - namespace dispositionActionModes - { + namespace dispositionActionModes { + /** User implicitely displayed or deleted the message (filter or * any other automatic action). */ extern VMIME_EXPORT const char* const AUTOMATIC; @@ -224,8 +224,8 @@ namespace vmime } /** Constants for disposition sending modes (RFC-3798). */ - namespace dispositionSendingModes - { + namespace dispositionSendingModes { + /** The MDN was sent because the MUA had previously been configured * to do so automatically. */ extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY; @@ -235,8 +235,8 @@ namespace vmime } /** Constants for disposition types (RFC-3798). */ - namespace dispositionTypes - { + namespace dispositionTypes { + /** Message has been displayed to the user. */ extern VMIME_EXPORT const char* const DISPLAYED; /** Message has been deleted without being displayed. */ @@ -246,8 +246,8 @@ namespace vmime } /** Constants for disposition modifiers (RFC-3798). */ - namespace dispositionModifiers - { + namespace dispositionModifiers { + extern VMIME_EXPORT const char* const ERROR; } } diff --git a/src/vmime/contentDisposition.cpp b/src/vmime/contentDisposition.cpp index 3cf92e27..1602273c 100644 --- a/src/vmime/contentDisposition.cpp +++ b/src/vmime/contentDisposition.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,107 +25,118 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { contentDisposition::contentDisposition() - : m_name(contentDispositionTypes::INLINE) -{ + : m_name(contentDispositionTypes::INLINE) { + } contentDisposition::contentDisposition(const string& name) - : m_name(utility::stringUtils::toLower(name)) -{ + : m_name(utility::stringUtils::toLower(name)) { + } contentDisposition::contentDisposition(const contentDisposition& type) - : headerFieldValue(), m_name(type.m_name) -{ + : headerFieldValue(), m_name(type.m_name) { + } -void contentDisposition::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ - m_name = utility::stringUtils::trim(utility::stringUtils::toLower - (string(buffer.begin() + position, buffer.begin() + end))); +void contentDisposition::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + + m_name = utility::stringUtils::trim( + utility::stringUtils::toLower( + string(buffer.begin() + position, buffer.begin() + end) + ) + ); setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void contentDisposition::generateImpl - (const generationContext& /* ctx */, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void contentDisposition::generateImpl( + const generationContext& /* ctx */, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + os << m_name; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + m_name.length(); + } } -contentDisposition& contentDisposition::operator=(const string& name) -{ +contentDisposition& contentDisposition::operator=(const string& name) { + m_name = utility::stringUtils::toLower(name); - return (*this); + return *this; } -bool contentDisposition::operator==(const contentDisposition& value) const -{ - return (utility::stringUtils::toLower(m_name) == value.m_name); +bool contentDisposition::operator==(const contentDisposition& value) const { + + return utility::stringUtils::toLower(m_name) == value.m_name; } -bool contentDisposition::operator!=(const contentDisposition& value) const -{ +bool contentDisposition::operator!=(const contentDisposition& value) const { + return !(*this == value); } -shared_ptr contentDisposition::clone() const -{ +shared_ptr contentDisposition::clone() const { + return make_shared (*this); } -void contentDisposition::copyFrom(const component& other) -{ +void contentDisposition::copyFrom(const component& other) { + const contentDisposition& d = dynamic_cast (other); m_name = d.m_name; } -contentDisposition& contentDisposition::operator=(const contentDisposition& other) -{ +contentDisposition& contentDisposition::operator=(const contentDisposition& other) { + copyFrom(other); - return (*this); + return *this; } -const string& contentDisposition::getName() const -{ - return (m_name); +const string& contentDisposition::getName() const { + + return m_name; } -void contentDisposition::setName(const string& name) -{ +void contentDisposition::setName(const string& name) { + m_name = name; } -const std::vector > contentDisposition::getChildComponents() -{ +const std::vector > contentDisposition::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/contentDisposition.hpp b/src/vmime/contentDisposition.hpp index c934b81d..636c0fb5 100644 --- a/src/vmime/contentDisposition.hpp +++ b/src/vmime/contentDisposition.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** Content disposition (basic type). */ +class VMIME_EXPORT contentDisposition : public headerFieldValue { -class VMIME_EXPORT contentDisposition : public headerFieldValue -{ public: contentDisposition(); @@ -78,18 +76,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/contentDispositionField.cpp b/src/vmime/contentDispositionField.cpp index efa99b4e..7e50680e 100644 --- a/src/vmime/contentDispositionField.cpp +++ b/src/vmime/contentDispositionField.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,132 +25,136 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { -contentDispositionField::contentDispositionField() -{ +contentDispositionField::contentDispositionField() { + } contentDispositionField::contentDispositionField(contentDispositionField&) - : parameterizedHeaderField() -{ + : parameterizedHeaderField() { + } -bool contentDispositionField::hasCreationDate() const -{ +bool contentDispositionField::hasCreationDate() const { + return hasParameter("creation-date"); } -const datetime contentDispositionField::getCreationDate() const -{ +const datetime contentDispositionField::getCreationDate() const { + shared_ptr param = findParameter("creation-date"); - if (param) + if (param) { return param->getValueAs (); - else + } else { return datetime::now(); + } } -void contentDispositionField::setCreationDate(const datetime& creationDate) -{ +void contentDispositionField::setCreationDate(const datetime& creationDate) { + getParameter("creation-date")->setValue(creationDate); } -bool contentDispositionField::hasModificationDate() const -{ +bool contentDispositionField::hasModificationDate() const { + return hasParameter("modification-date"); } -const datetime contentDispositionField::getModificationDate() const -{ +const datetime contentDispositionField::getModificationDate() const { + shared_ptr param = findParameter("modification-date"); - if (param) + if (param) { return param->getValueAs (); - else + } else { return datetime::now(); + } } -void contentDispositionField::setModificationDate(const datetime& modificationDate) -{ +void contentDispositionField::setModificationDate(const datetime& modificationDate) { + getParameter("modification-date")->setValue(modificationDate); } -bool contentDispositionField::hasReadDate() const -{ +bool contentDispositionField::hasReadDate() const { + return hasParameter("read-date"); } -const datetime contentDispositionField::getReadDate() const -{ +const datetime contentDispositionField::getReadDate() const { + shared_ptr param = findParameter("read-date"); - if (param) + if (param) { return param->getValueAs (); - else + } else { return datetime::now(); + } } -void contentDispositionField::setReadDate(const datetime& readDate) -{ +void contentDispositionField::setReadDate(const datetime& readDate) { + getParameter("read-date")->setValue(readDate); } -bool contentDispositionField::hasFilename() const -{ +bool contentDispositionField::hasFilename() const { + return hasParameter("filename"); } -const word contentDispositionField::getFilename() const -{ +const word contentDispositionField::getFilename() const { + shared_ptr param = findParameter("filename"); - if (param) + if (param) { return param->getValue(); - else + } else { return word(); + } } -void contentDispositionField::setFilename(const word& filename) -{ +void contentDispositionField::setFilename(const word& filename) { + getParameter("filename")->setValue(filename); } -bool contentDispositionField::hasSize() const -{ +bool contentDispositionField::hasSize() const { + return hasParameter("size"); } -const string contentDispositionField::getSize() const -{ +const string contentDispositionField::getSize() const { + shared_ptr param = findParameter("size"); - if (param) + if (param) { return param->getValue().getBuffer(); - else + } else { return ""; + } } -void contentDispositionField::setSize(const string& size) -{ +void contentDispositionField::setSize(const string& size) { + getParameter("size")->setValue(word(size, vmime::charsets::US_ASCII)); } diff --git a/src/vmime/contentDispositionField.hpp b/src/vmime/contentDispositionField.hpp index aac4c5de..89eb9076 100644 --- a/src/vmime/contentDispositionField.hpp +++ b/src/vmime/contentDispositionField.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,15 +32,13 @@ #include "vmime/word.hpp" -namespace vmime -{ +namespace vmime { /** Describes presentation information, as per RFC-2183. */ +class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField { -class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField -{ friend class headerFieldFactory; protected: diff --git a/src/vmime/contentHandler.cpp b/src/vmime/contentHandler.cpp index 3afe4324..0a0e6ade 100644 --- a/src/vmime/contentHandler.cpp +++ b/src/vmime/contentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,16 +24,15 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { // No encoding = "binary" encoding const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY); -contentHandler::~contentHandler() -{ +contentHandler::~contentHandler() { + } diff --git a/src/vmime/contentHandler.hpp b/src/vmime/contentHandler.hpp index f62af166..06c16c14 100644 --- a/src/vmime/contentHandler.hpp +++ b/src/vmime/contentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,12 +34,11 @@ #include "vmime/mediaType.hpp" -namespace vmime -{ +namespace vmime { -class VMIME_EXPORT contentHandler : public object -{ +class VMIME_EXPORT contentHandler : public object { + public: /** Used to specify that enclosed data is not encoded. */ @@ -63,7 +62,11 @@ public: * @param enc encoding for output * @param maxLineLength maximum line length for output */ - virtual void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const = 0; + virtual void generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength = lineLengthLimits::infinite + ) const = 0; /** Extract the contents into the specified stream. If needed, data * will be decoded before being written into the stream. @@ -74,7 +77,10 @@ public: * @param progress progress listener, or NULL if you do not * want to receive progress notifications */ - virtual void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; + virtual void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL + ) const = 0; /** Extract the contents into the specified stream, without * decoding it. It may be useful in case the encoding is not @@ -84,7 +90,10 @@ public: * @param progress progress listener, or NULL if you do not * want to receive progress notifications */ - virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; + virtual void extractRaw( + utility::outputStream& os, + utility::progressListener* progress = NULL + ) const = 0; /** Returns the actual length of data. WARNING: this can return 0 if no * length was specified when setting data of this object, or if the diff --git a/src/vmime/contentTypeField.cpp b/src/vmime/contentTypeField.cpp index 9e9ed4c2..ec4971da 100644 --- a/src/vmime/contentTypeField.cpp +++ b/src/vmime/contentTypeField.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,89 +25,90 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { -contentTypeField::contentTypeField() -{ +contentTypeField::contentTypeField() { + } contentTypeField::contentTypeField(contentTypeField&) - : parameterizedHeaderField() -{ + : parameterizedHeaderField() { + } -bool contentTypeField::hasBoundary() const -{ +bool contentTypeField::hasBoundary() const { + return hasParameter("boundary"); } -const string contentTypeField::getBoundary() const -{ +const string contentTypeField::getBoundary() const { + shared_ptr param = findParameter("boundary"); - if (param) + if (param) { return param->getValue().getBuffer(); - else + } else { return ""; + } } -void contentTypeField::setBoundary(const string& boundary) -{ +void contentTypeField::setBoundary(const string& boundary) { + getParameter("boundary")->setValue(word(boundary, vmime::charsets::US_ASCII)); } -bool contentTypeField::hasCharset() const -{ +bool contentTypeField::hasCharset() const { + return hasParameter("charset"); } -const charset contentTypeField::getCharset() const -{ +const charset contentTypeField::getCharset() const { + shared_ptr param = findParameter("charset"); - if (param) + if (param) { return param->getValueAs (); - else + } else { return charset(); + } } -void contentTypeField::setCharset(const charset& ch) -{ +void contentTypeField::setCharset(const charset& ch) { + getParameter("charset")->setValue(ch); } -bool contentTypeField::hasReportType() const -{ +bool contentTypeField::hasReportType() const { + return hasParameter("report-type"); } -const string contentTypeField::getReportType() const -{ +const string contentTypeField::getReportType() const { + shared_ptr param = findParameter("report-type"); - if (param) + if (param) { return param->getValue().getBuffer(); - else + } else { return ""; + } } -void contentTypeField::setReportType(const string& reportType) -{ +void contentTypeField::setReportType(const string& reportType) { + getParameter("report-type")->setValue(word(reportType, vmime::charsets::US_ASCII)); } } // vmime - diff --git a/src/vmime/contentTypeField.hpp b/src/vmime/contentTypeField.hpp index 8604c4a3..a63e7da0 100644 --- a/src/vmime/contentTypeField.hpp +++ b/src/vmime/contentTypeField.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,12 +31,11 @@ #include "vmime/charset.hpp" -namespace vmime -{ +namespace vmime { -class VMIME_EXPORT contentTypeField : public parameterizedHeaderField -{ +class VMIME_EXPORT contentTypeField : public parameterizedHeaderField { + friend class headerFieldFactory; protected: diff --git a/src/vmime/context.cpp b/src/vmime/context.cpp index 07fe4875..3fc4941a 100644 --- a/src/vmime/context.cpp +++ b/src/vmime/context.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,61 +24,60 @@ #include "vmime/context.hpp" -namespace vmime -{ +namespace vmime { context::context() - : m_internationalizedEmail(false) -{ + : m_internationalizedEmail(false) { + } context::context(const context& ctx) : object(), - m_internationalizedEmail(ctx.m_internationalizedEmail) -{ + m_internationalizedEmail(ctx.m_internationalizedEmail) { + } -context::~context() -{ +context::~context() { + } -bool context::getInternationalizedEmailSupport() const -{ +bool context::getInternationalizedEmailSupport() const { + return m_internationalizedEmail; } -void context::setInternationalizedEmailSupport(const bool support) -{ +void context::setInternationalizedEmailSupport(const bool support) { + m_internationalizedEmail = support; } -const charsetConverterOptions& context::getCharsetConversionOptions() const -{ +const charsetConverterOptions& context::getCharsetConversionOptions() const { + return m_charsetConvOptions; } -void context::setCharsetConversionOptions(const charsetConverterOptions& opts) -{ +void context::setCharsetConversionOptions(const charsetConverterOptions& opts) { + m_charsetConvOptions = opts; } -context& context::operator=(const context& ctx) -{ +context& context::operator=(const context& ctx) { + copyFrom(ctx); return *this; } -void context::copyFrom(const context& ctx) -{ +void context::copyFrom(const context& ctx) { + m_internationalizedEmail = ctx.m_internationalizedEmail; m_charsetConvOptions = ctx.m_charsetConvOptions; } diff --git a/src/vmime/context.hpp b/src/vmime/context.hpp index 767ec05a..1d009500 100644 --- a/src/vmime/context.hpp +++ b/src/vmime/context.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/charsetConverterOptions.hpp" -namespace vmime -{ +namespace vmime { /** Holds configuration parameters used either for parsing or generating messages. */ +class VMIME_EXPORT context : public object { -class VMIME_EXPORT context : public object -{ public: virtual ~context(); @@ -74,8 +72,8 @@ public: /** Switches between contexts temporarily. */ template - class switcher - { + class switcher { + public: /** Switches to the specified context. @@ -85,15 +83,15 @@ public: * @param newCtx new context */ switcher(CTX_CLASS& newCtx) - : m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) - { + : m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) { + CTX_CLASS::getDefaultContext().copyFrom(newCtx); } /** Restores back saved context. */ - ~switcher() - { + ~switcher() { + CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData); } diff --git a/src/vmime/dateTime.cpp b/src/vmime/dateTime.cpp index eca8e785..fd443030 100644 --- a/src/vmime/dateTime.cpp +++ b/src/vmime/dateTime.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,8 +31,7 @@ #include "vmime/utility/datetimeUtils.hpp" -namespace vmime -{ +namespace vmime { /* @@ -68,20 +67,24 @@ zone = "UT" / "GMT" ; Universal Time */ -void datetime::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void datetime::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* p = buffer.data() + position; // Parse the date and time value while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend) - { - if (parserHelpers::isAlpha(*p)) - { + if (p < pend) { + + if (parserHelpers::isAlpha(*p)) { + // Ignore week day while (p < pend && parserHelpers::isAlpha(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; @@ -91,34 +94,32 @@ void datetime::parseImpl bool dayParsed = false; - if (parserHelpers::isAlpha(*p)) - { + if (parserHelpers::isAlpha(*p)) { + // Ill-formed date/time, this may be the month, // so we skip day parsing (will be done later) - } - else - { + + } else { + while (p < pend && !parserHelpers::isDigit(*p)) ++p; - if (p < pend && parserHelpers::isDigit(*p)) - { + if (p < pend && parserHelpers::isDigit(*p)) { + // Month day int day = 0; - do - { + do { day = day * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); m_day = (day >= 1 && day <= 31) ? day : 1; while (p < pend && !parserHelpers::isSpace(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; - } - else - { + + } else { + m_day = 1; // Skip everything to the next field @@ -129,135 +130,131 @@ void datetime::parseImpl dayParsed = true; } - if (p < pend && parserHelpers::isAlpha(*p)) - { + if (p < pend && parserHelpers::isAlpha(*p)) { + // Month char_t month[4] = { 0 }; int monthLength = 0; - do - { + do { month[monthLength++] = *p; ++p; - } - while (monthLength < 3 && p < pend && parserHelpers::isAlpha(*p)); + } while (monthLength < 3 && p < pend && parserHelpers::isAlpha(*p)); while (p < pend && parserHelpers::isAlpha(*p)) ++p; - switch (month[0]) - { - case 'a': - case 'A': - { - if (month[1] == 'u' || month[1] == 'U') - m_month = AUGUST; - else - m_month = APRIL; // by default + switch (month[0]) { - break; - } - case 'd': - case 'D': - { - m_month = DECEMBER; - break; - } - case 'f': - case 'F': - { - m_month = FEBRUARY; - break; - } - case 'j': - case 'J': - { - if (month[1] == 'u' || month[1] == 'U') - { - if (month[2] == 'l' || month[2] == 'L') - m_month = JULY; - else // if (month[2] == 'n' || month[2] == 'N') - m_month = JUNE; + case 'a': + case 'A': { + + if (month[1] == 'u' || month[1] == 'U') + m_month = AUGUST; + else + m_month = APRIL; // by default + + break; } - else - { + case 'd': + case 'D': { + + m_month = DECEMBER; + break; + } + case 'f': + case 'F': { + + m_month = FEBRUARY; + break; + } + case 'j': + case 'J': { + + if (month[1] == 'u' || month[1] == 'U') { + + if (month[2] == 'l' || month[2] == 'L') { + m_month = JULY; + } else { // if (month[2] == 'n' || month[2] == 'N') + m_month = JUNE; + } + + } else { + + m_month = JANUARY; // by default + } + + break; + } + case 'm': + case 'M': { + + if ((month[1] == 'a' || month[1] == 'A') && + (month[2] == 'y' || month[2] == 'Y')) { + + m_month = MAY; + + } else { + + m_month = MARCH; // by default + } + + break; + } + case 'n': + case 'N': { + + m_month = NOVEMBER; + break; + } + case 'o': + case 'O': { + + m_month = OCTOBER; + break; + } + case 's': + case 'S': { + + m_month = SEPTEMBER; + break; + } + default: { + m_month = JANUARY; // by default + break; } - - break; - } - case 'm': - case 'M': - { - if ((month[1] == 'a' || month[1] == 'A') && - (month[2] == 'y' || month[2] == 'Y')) - { - m_month = MAY; - } - else - { - m_month = MARCH; // by default - } - - break; - } - case 'n': - case 'N': - { - m_month = NOVEMBER; - break; - } - case 'o': - case 'O': - { - m_month = OCTOBER; - break; - } - case 's': - case 'S': - { - m_month = SEPTEMBER; - break; - } - default: - { - m_month = JANUARY; // by default - break; - } - } while (p < pend && !parserHelpers::isSpace(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; - } - else - { + + } else { + m_month = JANUARY; - if (parserHelpers::isDigit(*p)) - { + if (parserHelpers::isDigit(*p)) { + // Here, we expected a month, but it maybe // a ill-formed date, so try to parse a year // (we don't skip anything). - } - else - { + + } else { + // Skip everything to the next field while (p < pend && !parserHelpers::isSpace(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; } } - if (!dayParsed && p < pend && parserHelpers::isDigit(*p)) - { + if (!dayParsed && p < pend && parserHelpers::isDigit(*p)) { + // Month day int day = 0; - do - { + do { day = day * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); m_day = (day >= 1 && day <= 31) ? day : 1; @@ -265,26 +262,24 @@ void datetime::parseImpl while (p < pend && parserHelpers::isSpace(*p)) ++p; } - if (p < pend && parserHelpers::isDigit(*p)) - { + if (p < pend && parserHelpers::isDigit(*p)) { + // Check for ill-formed date/time and try to recover - if (p + 2 < pend && *(p + 2) == ':') - { + if (p + 2 < pend && *(p + 2) == ':') { + // Skip year (default to current), and advance // to time parsing m_year = now().getYear(); - } - else - { + + } else { + // Year int year = 0; - do - { + do { year = year * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); if (year < 70) m_year = year + 2000; else if (year < 1000) m_year = year + 1900; @@ -293,9 +288,9 @@ void datetime::parseImpl while (p < pend && !parserHelpers::isSpace(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; } - } - else - { + + } else { + m_year = 1970; // Skip everything to the next field @@ -303,89 +298,83 @@ void datetime::parseImpl while (p < pend && parserHelpers::isSpace(*p)) ++p; } - if (p < pend && parserHelpers::isDigit(*p)) - { + if (p < pend && parserHelpers::isDigit(*p)) { + // Hour int hour = 0; - do - { + do { hour = hour * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); m_hour = (hour >= 0 && hour <= 23) ? hour : 0; while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend && *p == ':') - { + if (p < pend && *p == ':') { + ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend && parserHelpers::isDigit(*p)) - { + if (p < pend && parserHelpers::isDigit(*p)) { + // Minute int minute = 0; - do - { + do { minute = minute * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); m_minute = (minute >= 0 && minute <= 59) ? minute : 0; while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend && *p == ':') - { + if (p < pend && *p == ':') { + ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend && parserHelpers::isDigit(*p)) - { + if (p < pend && parserHelpers::isDigit(*p)) { + // Second int second = 0; - do - { + do { second = second * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); m_second = (second >= 0 && second <= 59) ? second : 0; while (p < pend && !parserHelpers::isSpace(*p)) ++p; while (p < pend && parserHelpers::isSpace(*p)) ++p; - } - else - { + + } else { + m_second = 0; } - } - else - { + + } else { + m_second = 0; } - } - else - { + + } else { + m_minute = 0; } - } - else - { + + } else { + m_minute = 0; } - } - else - { + + } else { + m_hour = 0; // Skip everything to the next field @@ -393,43 +382,40 @@ void datetime::parseImpl while (p < pend && parserHelpers::isSpace(*p)) ++p; } - if (p + 1 < pend && (*p == '+' || *p == '-') && parserHelpers::isDigit(*(p + 1))) - { + if (p + 1 < pend && (*p == '+' || *p == '-') && parserHelpers::isDigit(*(p + 1))) { + const char_t sign = *p; ++p; // Zone offset (in hour/minutes) int offset = 0; - do - { + do { offset = offset * 10 + (*p - '0'); ++p; - } - while (p < pend && parserHelpers::isDigit(*p)); + } while (p < pend && parserHelpers::isDigit(*p)); const int hourOff = offset / 100; const int minOff = offset % 100; - if (sign == '+') + if (sign == '+') { m_zone = hourOff * 60 + minOff; - else + } else { m_zone = -(hourOff * 60 + minOff); - } - else if (p < pend && isalpha(*p)) - { + } + + } else if (p < pend && isalpha(*p)) { + bool done = false; // Zone offset (Time zone name) char_t zone[4] = { 0 }; int zoneLength = 0; - do - { + do { zone[zoneLength++] = *p; ++p; - } - while (zoneLength < 3 && p < pend); + } while (zoneLength < 3 && p < pend); switch (zone[0]) { @@ -451,12 +437,13 @@ void datetime::parseImpl case 'e': case 'E': { - if (zoneLength >= 2) - { - if (zone[1] == 's' || zone[1] == 'S') + if (zoneLength >= 2) { + + if (zone[1] == 's' || zone[1] == 'S') { m_zone = EST; - else + } else { m_zone = EDT; + } done = true; } @@ -464,14 +451,15 @@ void datetime::parseImpl break; } case 'm': - case 'M': - { - if (zoneLength >= 2) - { - if (zone[1] == 's' || zone[1] == 'S') + case 'M': { + + if (zoneLength >= 2) { + + if (zone[1] == 's' || zone[1] == 'S') { m_zone = MST; - else + } else { m_zone = MDT; + } done = true; } @@ -479,14 +467,15 @@ void datetime::parseImpl break; } case 'p': - case 'P': - { - if (zoneLength >= 2) - { - if (zone[1] == 's' || zone[1] == 'S') + case 'P': { + + if (zoneLength >= 2) { + + if (zone[1] == 's' || zone[1] == 'S') { m_zone = PST; - else + } else { m_zone = PDT; + } done = true; } @@ -496,10 +485,10 @@ void datetime::parseImpl case 'g': case 'G': case 'u': - case 'U': - { - if (zoneLength >= 2) - { + case 'U': { + + if (zoneLength >= 2) { + m_zone = GMT; // = UTC done = true; } @@ -509,16 +498,16 @@ void datetime::parseImpl } - if (!done) - { + if (!done) { + const char_t z = zone[0]; // Military time zone - if (z != 'j' && z != 'J') - { + if (z != 'j' && z != 'J') { + typedef std::map Map; - static const Map::value_type offsetMapInit[] = - { + static const Map::value_type offsetMapInit[] = { + Map::value_type('a', -60), Map::value_type('b', -120), Map::value_type('c', -180), @@ -547,31 +536,34 @@ void datetime::parseImpl Map::value_type('z', 0), }; - static const Map offsetMap - (::vmime::begin(offsetMapInit), - ::vmime::end(offsetMapInit)); + + static const Map offsetMap( + ::vmime::begin(offsetMapInit), + ::vmime::end(offsetMapInit) + ); Map::const_iterator pos = offsetMap.find(parserHelpers::toLower(z)); - if (pos != offsetMap.end()) + if (pos != offsetMap.end()) { m_zone = (*pos).second; - else + } else { m_zone = GMT; - } - else - { + } + + } else { + m_zone = GMT; } } - } - else - { + + } else { + m_zone = 0; } - } - else - { + + } else { + m_year = 1970; m_month = JANUARY; m_day = 1; @@ -585,20 +577,26 @@ void datetime::parseImpl setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void datetime::generateImpl - (const generationContext& /* ctx */, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ - static const char* dayNames[] = - { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - static const char* monthNames[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; +void datetime::generateImpl( + const generationContext& /* ctx */, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + + static const char* dayNames[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char* monthNames[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; const int z = ((m_zone < 0) ? -m_zone : m_zone); const int zh = z / 60; @@ -618,64 +616,89 @@ void datetime::generateImpl const string& str = oss.str(); os << str; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + str.length(); + } } datetime::datetime() : m_year(1970), m_month(1), m_day(1), - m_hour(0), m_minute(0), m_second(0), m_zone(0) -{ + m_hour(0), m_minute(0), m_second(0), m_zone(0) { + } datetime::datetime(const int year, const int month, const int day) : m_year(year), m_month(month), m_day(day), - m_hour(0), m_minute(0), m_second(0), m_zone(0) -{ + m_hour(0), m_minute(0), m_second(0), m_zone(0) { + } -datetime::datetime(const int year, const int month, const int day, - const int hour, const int minute, const int second, - const int zone) - : m_year(year), m_month(month), m_day(day), - m_hour(hour), m_minute(minute), m_second(second), m_zone(zone) -{ +datetime::datetime( + const int year, + const int month, + const int day, + const int hour, + const int minute, + const int second, + const int zone +) + : m_year(year), + m_month(month), + m_day(day), + m_hour(hour), + m_minute(minute), + m_second(second), + m_zone(zone) { + } datetime::datetime(const datetime& d) - : headerFieldValue(), m_year(d.m_year), m_month(d.m_month), m_day(d.m_day), - m_hour(d.m_hour), m_minute(d.m_minute), m_second(d.m_second), m_zone(d.m_zone) -{ + : headerFieldValue(), + m_year(d.m_year), + m_month(d.m_month), + m_day(d.m_day), + m_hour(d.m_hour), + m_minute(d.m_minute), + m_second(d.m_second), + m_zone(d.m_zone) { + } -datetime::datetime(const time_t t, const int zone) -{ +datetime::datetime(const time_t t, const int zone) { #if VMIME_HAVE_LOCALTIME_S + struct tm tms; - if (!gmtime_s(&tms, &t)) + if (!gmtime_s(&tms, &t)) { localtime_s(&tms, &t); + } + #elif VMIME_HAVE_LOCALTIME_R struct tm tms; - if (!gmtime_r(&t, &tms)) + if (!gmtime_r(&t, &tms)) { localtime_r(&t, &tms); + } + #else + struct tm* gtm = gmtime(&t); struct tm* ltm = localtime(&t); struct tm tms; - if (gtm) + if (gtm) { tms = *gtm; - else if (ltm) + } else if (ltm) { tms = *ltm; + } + #endif m_year = tms.tm_year + 1900; @@ -688,19 +711,19 @@ datetime::datetime(const time_t t, const int zone) } -datetime::datetime(const string& date) -{ +datetime::datetime(const string& date) { + parse(date); } -datetime::~datetime() -{ +datetime::~datetime() { + } -void datetime::copyFrom(const component& other) -{ +void datetime::copyFrom(const component& other) { + const datetime& d = dynamic_cast (other); m_year = d.m_year; @@ -713,22 +736,22 @@ void datetime::copyFrom(const component& other) } -datetime& datetime::operator=(const datetime& other) -{ +datetime& datetime::operator=(const datetime& other) { + copyFrom(other); - return (*this); + return *this; } -datetime& datetime::operator=(const string& s) -{ +datetime& datetime::operator=(const string& s) { + parse(s); - return (*this); + return *this; } -void datetime::getTime(int& hour, int& minute, int& second, int& zone) const -{ +void datetime::getTime(int& hour, int& minute, int& second, int& zone) const { + hour = m_hour; minute = m_minute; second = m_second; @@ -736,25 +759,29 @@ void datetime::getTime(int& hour, int& minute, int& second, int& zone) const } -void datetime::getTime(int& hour, int& minute, int& second) const -{ +void datetime::getTime(int& hour, int& minute, int& second) const { + hour = m_hour; minute = m_minute; second = m_second; } -void datetime::getDate(int& year, int& month, int& day) const -{ +void datetime::getDate(int& year, int& month, int& day) const { + year = m_year; month = m_month; day = m_day; } -void datetime::setTime(const int hour, const int minute, - const int second, const int zone) -{ +void datetime::setTime( + const int hour, + const int minute, + const int second, + const int zone +) { + m_hour = hour; m_minute = minute; m_second = second; @@ -762,40 +789,44 @@ void datetime::setTime(const int hour, const int minute, } -void datetime::setDate(const int year, const int month, const int day) -{ +void datetime::setDate( + const int year, + const int month, + const int day +) { + m_year = year; m_month = month; m_day = day; } -const datetime datetime::now() -{ - return (platform::getHandler()->getCurrentLocalTime()); +const datetime datetime::now() { + + return platform::getHandler()->getCurrentLocalTime(); } -shared_ptr datetime::clone() const -{ +shared_ptr datetime::clone() const { + return make_shared (*this); } -const std::vector > datetime::getChildComponents() -{ +const std::vector > datetime::getChildComponents() { + return std::vector >(); } -int datetime::getYear() const { return (m_year); } -int datetime::getMonth() const { return (m_month); } -int datetime::getDay() const { return (m_day); } -int datetime::getHour() const { return (m_hour); } -int datetime::getMinute() const { return (m_minute); } -int datetime::getSecond() const { return (m_second); } -int datetime::getZone() const { return (m_zone); } -int datetime::getWeekDay() const { return (utility::datetimeUtils::getDayOfWeek(m_year, m_month, m_day)); } +int datetime::getYear() const { return m_year; } +int datetime::getMonth() const { return m_month; } +int datetime::getDay() const { return m_day; } +int datetime::getHour() const { return m_hour; } +int datetime::getMinute() const { return m_minute; } +int datetime::getSecond() const { return m_second; } +int datetime::getZone() const { return m_zone; } +int datetime::getWeekDay() const { return utility::datetimeUtils::getDayOfWeek(m_year, m_month, m_day); } int datetime::getWeek() const { return utility::datetimeUtils::getWeekOfYear(m_year, m_month, m_day); } void datetime::setYear(const int year) { m_year = year; } @@ -807,87 +838,87 @@ void datetime::setSecond(const int second) { m_second = second; } void datetime::setZone(const int zone) { m_zone = zone; } -bool datetime::operator==(const datetime& other) const -{ +bool datetime::operator==(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return (ut1.m_year == ut2.m_year && - ut1.m_month == ut2.m_month && - ut1.m_day == ut2.m_day && - ut1.m_hour == ut2.m_hour && - ut1.m_minute == ut2.m_minute && - ut1.m_second == ut2.m_second); + return ut1.m_year == ut2.m_year && + ut1.m_month == ut2.m_month && + ut1.m_day == ut2.m_day && + ut1.m_hour == ut2.m_hour && + ut1.m_minute == ut2.m_minute && + ut1.m_second == ut2.m_second; } -bool datetime::operator!=(const datetime& other) const -{ +bool datetime::operator!=(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return (ut1.m_year != ut2.m_year || - ut1.m_month != ut2.m_month || - ut1.m_day != ut2.m_day || - ut1.m_hour != ut2.m_hour || - ut1.m_minute != ut2.m_minute || - ut1.m_second != ut2.m_second); + return ut1.m_year != ut2.m_year || + ut1.m_month != ut2.m_month || + ut1.m_day != ut2.m_day || + ut1.m_hour != ut2.m_hour || + ut1.m_minute != ut2.m_minute || + ut1.m_second != ut2.m_second; } -bool datetime::operator<(const datetime& other) const -{ +bool datetime::operator<(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return ((ut1.m_year < ut2.m_year) || - ((ut1.m_year == ut2.m_year) && ((ut1.m_month < ut2.m_month) || - ((ut1.m_month == ut2.m_month) && ((ut1.m_day < ut2.m_day) || - ((ut1.m_day == ut2.m_day) && ((ut1.m_hour < ut2.m_hour) || - ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute < ut2.m_minute) || - ((ut1.m_minute == ut2.m_minute) && ((ut1.m_second < ut2.m_second)))))))))))); + return (ut1.m_year < ut2.m_year) || + ((ut1.m_year == ut2.m_year) && ((ut1.m_month < ut2.m_month) || + ((ut1.m_month == ut2.m_month) && ((ut1.m_day < ut2.m_day) || + ((ut1.m_day == ut2.m_day) && ((ut1.m_hour < ut2.m_hour) || + ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute < ut2.m_minute) || + ((ut1.m_minute == ut2.m_minute) && ((ut1.m_second < ut2.m_second))))))))))); } -bool datetime::operator<=(const datetime& other) const -{ +bool datetime::operator<=(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return ((ut1.m_year < ut2.m_year) || - ((ut1.m_year == ut2.m_year) && ((ut1.m_month < ut2.m_month) || - ((ut1.m_month == ut2.m_month) && ((ut1.m_day < ut2.m_day) || - ((ut1.m_day == ut2.m_day) && ((ut1.m_hour < ut2.m_hour) || - ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute < ut2.m_minute) || - ((ut1.m_minute == ut2.m_minute) && ((ut1.m_second <= ut2.m_second)))))))))))); + return (ut1.m_year < ut2.m_year) || + ((ut1.m_year == ut2.m_year) && ((ut1.m_month < ut2.m_month) || + ((ut1.m_month == ut2.m_month) && ((ut1.m_day < ut2.m_day) || + ((ut1.m_day == ut2.m_day) && ((ut1.m_hour < ut2.m_hour) || + ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute < ut2.m_minute) || + ((ut1.m_minute == ut2.m_minute) && ((ut1.m_second <= ut2.m_second))))))))))); } -bool datetime::operator>(const datetime& other) const -{ +bool datetime::operator>(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return ((ut1.m_year > ut2.m_year) || - ((ut1.m_year == ut2.m_year) && ((ut1.m_month > ut2.m_month) || - ((ut1.m_month == ut2.m_month) && ((ut1.m_day > ut2.m_day) || - ((ut1.m_day == ut2.m_day) && ((ut1.m_hour > ut2.m_hour) || - ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute > ut2.m_minute) || - ((ut1.m_minute == ut2.m_minute) && (ut1.m_second > ut2.m_second))))))))))); + return (ut1.m_year > ut2.m_year) || + ((ut1.m_year == ut2.m_year) && ((ut1.m_month > ut2.m_month) || + ((ut1.m_month == ut2.m_month) && ((ut1.m_day > ut2.m_day) || + ((ut1.m_day == ut2.m_day) && ((ut1.m_hour > ut2.m_hour) || + ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute > ut2.m_minute) || + ((ut1.m_minute == ut2.m_minute) && (ut1.m_second > ut2.m_second)))))))))); } -bool datetime::operator>=(const datetime& other) const -{ +bool datetime::operator>=(const datetime& other) const { + const datetime ut1 = utility::datetimeUtils::toUniversalTime(*this); const datetime ut2 = utility::datetimeUtils::toUniversalTime(other); - return ((ut1.m_year > ut2.m_year) || - ((ut1.m_year == ut2.m_year) && ((ut1.m_month > ut2.m_month) || - ((ut1.m_month == ut2.m_month) && ((ut1.m_day > ut2.m_day) || - ((ut1.m_day == ut2.m_day) && ((ut1.m_hour > ut2.m_hour) || - ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute > ut2.m_minute) || - ((ut1.m_minute == ut2.m_minute) && (ut1.m_second >= ut2.m_second))))))))))); + return (ut1.m_year > ut2.m_year) || + ((ut1.m_year == ut2.m_year) && ((ut1.m_month > ut2.m_month) || + ((ut1.m_month == ut2.m_month) && ((ut1.m_day > ut2.m_day) || + ((ut1.m_day == ut2.m_day) && ((ut1.m_hour > ut2.m_hour) || + ((ut1.m_hour == ut2.m_hour) && ((ut1.m_minute > ut2.m_minute) || + ((ut1.m_minute == ut2.m_minute) && (ut1.m_second >= ut2.m_second)))))))))); } diff --git a/src/vmime/dateTime.hpp b/src/vmime/dateTime.hpp index 7af63040..64e8dad4 100644 --- a/src/vmime/dateTime.hpp +++ b/src/vmime/dateTime.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,21 +31,31 @@ #include -namespace vmime -{ +namespace vmime { /** Date and time (basic type). */ +class VMIME_EXPORT datetime : public headerFieldValue { -class VMIME_EXPORT datetime : public headerFieldValue -{ public: // Constructors datetime(); - datetime(const int year, const int month, const int day); - datetime(const int year, const int month, const int day, const int hour, const int minute, const int second, const int zone = GMT); + datetime( + const int year, + const int month, + const int day + ); + datetime( + const int year, + const int month, + const int day, + const int hour, + const int minute, + const int second, + const int zone = GMT + ); datetime(const datetime& d); datetime(const string& date); datetime(const time_t t, const int zone = GMT); @@ -54,8 +64,8 @@ public: ~datetime(); // Some time zones (in minutes) - enum TimeZones - { + enum TimeZones { + GMT_12 = -720, // GMT-12h GMT_11 = -660, // GMT-11h GMT_10 = -600, // GMT-10h @@ -124,8 +134,8 @@ public: }; // Months list - enum Months - { + enum Months { + // Long JANUARY = 1, FEBRUARY = 2, @@ -155,8 +165,8 @@ public: }; // Days of week list - enum DaysOfWeek - { + enum DaysOfWeek { + // Long SUNDAY = 0, MONDAY = 1, @@ -242,18 +252,20 @@ public: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/defaultAttachment.cpp b/src/vmime/defaultAttachment.cpp index 2eb9289a..36eaa3cf 100644 --- a/src/vmime/defaultAttachment.cpp +++ b/src/vmime/defaultAttachment.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,57 +28,75 @@ #include "vmime/encoding.hpp" -namespace vmime -{ +namespace vmime { -defaultAttachment::defaultAttachment() -{ +defaultAttachment::defaultAttachment() { + } -defaultAttachment::defaultAttachment(const shared_ptr & data, - const encoding& enc, const mediaType& type, const text& desc, const word& name) - : m_type(type), m_desc(desc), m_data(data), m_encoding(enc), m_name(name) -{ +defaultAttachment::defaultAttachment( + const shared_ptr & data, + const encoding& enc, + const mediaType& type, + const text& desc, + const word& name +) + : m_type(type), + m_desc(desc), + m_data(data), + m_encoding(enc), + m_name(name) { + } -defaultAttachment::defaultAttachment(const shared_ptr & data, - const mediaType& type, const text& desc, const word& name) - : m_type(type), m_desc(desc), m_data(data), - m_encoding(encoding::decide(data)), m_name(name) -{ +defaultAttachment::defaultAttachment( + const shared_ptr & data, + const mediaType& type, + const text& desc, + const word& name +) + : m_type(type), + m_desc(desc), + m_data(data), + m_encoding(encoding::decide(data)), + m_name(name) { + } defaultAttachment::defaultAttachment(const defaultAttachment& attach) - : attachment(), m_type(attach.m_type), m_desc(attach.m_desc), + : attachment(), + m_type(attach.m_type), + m_desc(attach.m_desc), m_data(vmime::clone(attach.m_data)), - m_encoding(attach.m_encoding), m_name(attach.m_name) -{ + m_encoding(attach.m_encoding), + m_name(attach.m_name) { + } -defaultAttachment::~defaultAttachment() -{ +defaultAttachment::~defaultAttachment() { + } -defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach) -{ +defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach) { + m_type = attach.m_type; m_desc = attach.m_desc; m_name = attach.m_name; m_data = vmime::clone(attach.m_data); m_encoding = attach.m_encoding; - return (*this); + return *this; } -void defaultAttachment::generateIn(const shared_ptr & parent) const -{ +void defaultAttachment::generateIn(const shared_ptr & parent) const { + // Create and append a new part for this attachment shared_ptr part = make_shared (); parent->getBody()->appendPart(part); @@ -87,8 +105,8 @@ void defaultAttachment::generateIn(const shared_ptr & parent) const } -void defaultAttachment::generatePart(const shared_ptr & part) const -{ +void defaultAttachment::generatePart(const shared_ptr & part) const { + // Set header fields part->getHeader()->ContentType()->setValue(m_type); if (!m_desc.isEmpty()) part->getHeader()->ContentDescription()->setValue(m_desc); @@ -101,44 +119,44 @@ void defaultAttachment::generatePart(const shared_ptr & part) const } -const mediaType defaultAttachment::getType() const -{ +const mediaType defaultAttachment::getType() const { + return m_type; } -const text defaultAttachment::getDescription() const -{ +const text defaultAttachment::getDescription() const { + return m_desc; } -const word defaultAttachment::getName() const -{ +const word defaultAttachment::getName() const { + return m_name; } -const shared_ptr defaultAttachment::getData() const -{ +const shared_ptr defaultAttachment::getData() const { + return m_data; } -const encoding defaultAttachment::getEncoding() const -{ +const encoding defaultAttachment::getEncoding() const { + return m_encoding; } -shared_ptr defaultAttachment::getPart() const -{ +shared_ptr defaultAttachment::getPart() const { + return null; } -shared_ptr defaultAttachment::getHeader() const -{ +shared_ptr defaultAttachment::getHeader() const { + return null; } diff --git a/src/vmime/defaultAttachment.hpp b/src/vmime/defaultAttachment.hpp index 817e834b..ce1c603c 100644 --- a/src/vmime/defaultAttachment.hpp +++ b/src/vmime/defaultAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/encoding.hpp" -namespace vmime -{ +namespace vmime { /** Default implementation for attachments. */ +class VMIME_EXPORT defaultAttachment : public attachment { -class VMIME_EXPORT defaultAttachment : public attachment -{ protected: // For use in derived classes. @@ -45,8 +43,21 @@ protected: public: - defaultAttachment(const shared_ptr & data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); - defaultAttachment(const shared_ptr & data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); + defaultAttachment( + const shared_ptr & data, + const encoding& enc, + const mediaType& type, + const text& desc = NULL_TEXT, + const word& name = NULL_WORD + ); + + defaultAttachment( + const shared_ptr & data, + const mediaType& type, + const text& desc = NULL_TEXT, + const word& name = NULL_WORD + ); + defaultAttachment(const defaultAttachment& attach); ~defaultAttachment(); diff --git a/src/vmime/disposition.cpp b/src/vmime/disposition.cpp index 352d3251..6e10cb9d 100644 --- a/src/vmime/disposition.cpp +++ b/src/vmime/disposition.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -27,25 +27,30 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { -disposition::disposition() -{ +disposition::disposition() { + } -disposition::disposition(const string& actionMode, const string& sendingMode, - const string& type, const string& modifier) - : m_actionMode(actionMode), m_sendingMode(sendingMode), m_type(type) -{ +disposition::disposition( + const string& actionMode, + const string& sendingMode, + const string& type, + const string& modifier +) + : m_actionMode(actionMode), + m_sendingMode(sendingMode), + m_type(type) { + m_modifiers.push_back(modifier); } -shared_ptr disposition::clone() const -{ +shared_ptr disposition::clone() const { + shared_ptr disp = make_shared (); disp->m_actionMode = m_actionMode; @@ -55,12 +60,12 @@ shared_ptr disposition::clone() const std::copy(m_modifiers.begin(), m_modifiers.end(), disp->m_modifiers.begin()); - return (disp); + return disp; } -void disposition::copyFrom(const component& other) -{ +void disposition::copyFrom(const component& other) { + const disposition& disp = dynamic_cast (other); m_actionMode = disp.m_actionMode; @@ -72,71 +77,71 @@ void disposition::copyFrom(const component& other) } -disposition& disposition::operator=(const disposition& other) -{ +disposition& disposition::operator=(const disposition& other) { + copyFrom(other); - return (*this); + return *this; } -const std::vector > disposition::getChildComponents() -{ +const std::vector > disposition::getChildComponents() { + return std::vector >(); } -void disposition::setActionMode(const string& mode) -{ +void disposition::setActionMode(const string& mode) { + m_actionMode = mode; } -const string& disposition::getActionMode() const -{ - return (m_actionMode); +const string& disposition::getActionMode() const { + + return m_actionMode; } -void disposition::setSendingMode(const string& mode) -{ +void disposition::setSendingMode(const string& mode) { + m_sendingMode = mode; } -const string& disposition::getSendingMode() const -{ - return (m_sendingMode); +const string& disposition::getSendingMode() const { + + return m_sendingMode; } -void disposition::setType(const string& type) -{ +void disposition::setType(const string& type) { + m_type = type; } -const string& disposition::getType() const -{ - return (m_type); +const string& disposition::getType() const { + + return m_type; } -void disposition::addModifier(const string& modifier) -{ - if (!hasModifier(modifier)) +void disposition::addModifier(const string& modifier) { + + if (!hasModifier(modifier)) { m_modifiers.push_back(utility::stringUtils::toLower(modifier)); + } } -void disposition::removeModifier(const string& modifier) -{ +void disposition::removeModifier(const string& modifier) { + const string modifierLC = utility::stringUtils::toLower(modifier); for (std::vector ::iterator it = m_modifiers.begin() ; - it != m_modifiers.end() ; ++it) - { - if (*it == modifierLC) - { + it != m_modifiers.end() ; ++it) { + + if (*it == modifierLC) { m_modifiers.erase(it); break; } @@ -144,37 +149,42 @@ void disposition::removeModifier(const string& modifier) } -void disposition::removeAllModifiers() -{ +void disposition::removeAllModifiers() { + m_modifiers.clear(); } -bool disposition::hasModifier(const string& modifier) const -{ +bool disposition::hasModifier(const string& modifier) const { + const string modifierLC = utility::stringUtils::toLower(modifier); for (std::vector ::const_iterator it = m_modifiers.begin() ; - it != m_modifiers.end() ; ++it) - { - if (*it == modifierLC) - return (true); + it != m_modifiers.end() ; ++it) { + + if (*it == modifierLC) { + return true; + } } - return (false); + return false; } -const std::vector disposition::getModifierList() const -{ - return (m_modifiers); +const std::vector disposition::getModifierList() const { + + return m_modifiers; } -void disposition::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void disposition::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + // disposition-mode ";" disposition-type // [ "/" disposition-modifier *( "," disposition-modifier ) ] // @@ -182,105 +192,116 @@ void disposition::parseImpl size_t pos = position; - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } // -- disposition-mode const size_t modeStart = pos; size_t modeEnd = pos; - while (pos < end && buffer[pos] != ';') - { + while (pos < end && buffer[pos] != ';') { ++modeEnd; ++pos; } - while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1])) + while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1])) { --modeEnd; + } const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd); const size_t slash = mode.find('/'); - if (slash != string::npos) - { + if (slash != string::npos) { + m_actionMode = string(mode.begin(), mode.begin() + slash); m_sendingMode = string(mode.begin() + slash + 1, mode.end()); - } - else - { + + } else { + m_actionMode = mode; m_sendingMode.clear(); } - if (pos < end) - { + if (pos < end) { // Skip ';' ++pos; } - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } // -- disposition-type const size_t typeStart = pos; size_t typeEnd = pos; - while (pos < end && buffer[pos] != '/') - { + while (pos < end && buffer[pos] != '/') { ++typeEnd; ++pos; } - while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1])) + while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1])) { --typeEnd; + } m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd); m_modifiers.clear(); - if (pos < end) // modifiers follow - { + if (pos < end) { // modifiers follow + // Skip '/' ++pos; - while (pos < end) - { - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end) { + + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } const size_t modifierStart = pos; size_t modifierEnd = pos; - while (pos < end && buffer[pos] != ',') - { + while (pos < end && buffer[pos] != ',') { ++modifierEnd; ++pos; } - while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1])) + while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1])) { --modifierEnd; + } - if (modifierEnd > modifierStart) - { - m_modifiers.push_back(string(buffer.begin() + modifierStart, - buffer.begin() + modifierEnd)); + if (modifierEnd > modifierStart) { + + m_modifiers.push_back( + string( + buffer.begin() + modifierStart, + buffer.begin() + modifierEnd + ) + ); } // Skip ',' - if (pos < end) + if (pos < end) { ++pos; + } } } - if (newPosition) + if (newPosition) { *newPosition = pos; + } } -void disposition::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void disposition::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + size_t pos = curLinePos; const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode); @@ -289,8 +310,7 @@ void disposition::generateImpl os << actionMode << "/" << sendingMode << ";"; pos += actionMode.length() + 1 + sendingMode.length() + 1; - if (pos > ctx.getMaxLineLength()) - { + if (pos > ctx.getMaxLineLength()) { os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE_LENGTH; } @@ -300,18 +320,19 @@ void disposition::generateImpl os << type; pos += type.length(); - if (m_modifiers.size() >= 1) - { - for (std::vector ::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i) - { + if (m_modifiers.size() >= 1) { + + for (std::vector ::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i) { + const string mod = utility::stringUtils::trim(m_modifiers[i]); - if (!mod.empty()) - { - if (n == 0) + if (!mod.empty()) { + + if (n == 0) { os << "/"; - else + } else { os << ","; + } os << mod; pos += 1 + mod.length(); @@ -321,8 +342,9 @@ void disposition::generateImpl } } - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } diff --git a/src/vmime/disposition.hpp b/src/vmime/disposition.hpp index 7322c21d..d4b023bf 100644 --- a/src/vmime/disposition.hpp +++ b/src/vmime/disposition.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,19 +31,22 @@ #include -namespace vmime -{ +namespace vmime { /** Disposition - from RFC-3798 (basic type). */ +class VMIME_EXPORT disposition : public headerFieldValue { -class VMIME_EXPORT disposition : public headerFieldValue -{ public: disposition(); - disposition(const string& actionMode, const string& sendingMode, const string& type, const string& modifier); + disposition( + const string& actionMode, + const string& sendingMode, + const string& type, + const string& modifier + ); shared_ptr clone() const; @@ -137,18 +140,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; @@ -156,4 +161,3 @@ protected: #endif // VMIME_DISPOSITION_HPP_INCLUDED - diff --git a/src/vmime/emailAddress.cpp b/src/vmime/emailAddress.cpp index 08c7a35b..1be678a5 100644 --- a/src/vmime/emailAddress.cpp +++ b/src/vmime/emailAddress.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,8 +31,7 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { /** Decode an IDNA-encoded domain name ("xn--5rtw95l.xn--wgv71a") @@ -41,48 +40,52 @@ namespace vmime * @param idnaDomain domain name encoded with IDNA * @return decoded domain name in UTF-8 */ -static const string domainNameFromIDNA(const string& idnaDomain) -{ +static const string domainNameFromIDNA(const string& idnaDomain) { + std::ostringstream domainName; size_t p = 0; for (size_t n = idnaDomain.find('.', p) ; - (n = idnaDomain.find('.', p)) != string::npos ; p = n + 1) - { + (n = idnaDomain.find('.', p)) != string::npos ; p = n + 1) { + const string encodedPart(idnaDomain.begin() + p, idnaDomain.begin() + n); if (encodedPart.length() > 4 && encodedPart[0] == 'x' && encodedPart[1] == 'n' && - encodedPart[2] == '-' && encodedPart[3] == '-') - { + encodedPart[2] == '-' && encodedPart[3] == '-') { + string decodedPart; - charset::convert(encodedPart, decodedPart, - vmime::charsets::IDNA, vmime::charsets::UTF_8); + charset::convert( + encodedPart, decodedPart, + vmime::charsets::IDNA, vmime::charsets::UTF_8 + ); domainName << decodedPart << '.'; - } - else - { + + } else { + domainName << encodedPart << '.'; // not encoded } } - if (p < idnaDomain.length()) - { + if (p < idnaDomain.length()) { + const string encodedPart(idnaDomain.begin() + p, idnaDomain.end()); if (encodedPart.length() > 4 && encodedPart[0] == 'x' && encodedPart[1] == 'n' && - encodedPart[2] == '-' && encodedPart[3] == '-') - { + encodedPart[2] == '-' && encodedPart[3] == '-') { + string decodedPart; - charset::convert(encodedPart, decodedPart, - vmime::charsets::IDNA, vmime::charsets::UTF_8); + charset::convert( + encodedPart, decodedPart, + vmime::charsets::IDNA, vmime::charsets::UTF_8 + ); domainName << decodedPart; - } - else - { + + } else { + domainName << encodedPart; // not encoded } } @@ -97,26 +100,30 @@ static const string domainNameFromIDNA(const string& idnaDomain) * @param domainName domain name in UTF-8 * @return domain name encoded with IDNA */ -static const string domainNameToIDNA(const string& domainName) -{ +static const string domainNameToIDNA(const string& domainName) { + std::ostringstream idnaDomain; size_t p = 0; for (size_t n = domainName.find('.', p) ; - (n = domainName.find('.', p)) != string::npos ; p = n + 1) - { + (n = domainName.find('.', p)) != string::npos ; p = n + 1) { + string idnaPart; - charset::convert(string(domainName.begin() + p, domainName.begin() + n), - idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA); + charset::convert( + string(domainName.begin() + p, domainName.begin() + n), idnaPart, + vmime::charsets::UTF_8, vmime::charsets::IDNA + ); idnaDomain << idnaPart << '.'; } - if (p < domainName.length()) - { + if (p < domainName.length()) { + string idnaPart; - charset::convert(string(domainName.begin() + p, domainName.end()), - idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA); + charset::convert( + string(domainName.begin() + p, domainName.end()), idnaPart, + vmime::charsets::UTF_8, vmime::charsets::IDNA + ); idnaDomain << idnaPart; } @@ -127,52 +134,60 @@ static const string domainNameToIDNA(const string& domainName) -emailAddress::emailAddress() -{ +emailAddress::emailAddress() { + } emailAddress::emailAddress(const emailAddress& eml) - : component(), m_localName(eml.m_localName), m_domainName(eml.m_domainName) -{ + : component(), + m_localName(eml.m_localName), + m_domainName(eml.m_domainName) { + } -emailAddress::emailAddress(const string& email) -{ +emailAddress::emailAddress(const string& email) { + parse(email); } -emailAddress::emailAddress(const char* email) -{ +emailAddress::emailAddress(const char* email) { + parse(email); } emailAddress::emailAddress(const string& localName, const string& domainName) - : component(), m_localName(word(localName, vmime::charsets::UTF_8)), - m_domainName(word(domainName, vmime::charsets::UTF_8)) -{ + : component(), + m_localName(word(localName, vmime::charsets::UTF_8)), + m_domainName(word(domainName, vmime::charsets::UTF_8)) { + } emailAddress::emailAddress(const word& localName, const word& domainName) - : component(), m_localName(localName), m_domainName(domainName) -{ + : component(), + m_localName(localName), + m_domainName(domainName) { + } -void emailAddress::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void emailAddress::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; - enum ParserStates - { + enum ParserStates { State_Before, State_LocalPartStart, State_LocalPartMiddle, @@ -199,361 +214,367 @@ void emailAddress::parseImpl int commentLevel = 0; bool localPartIsRFC2047 = false; - while (p < pend && !stop) - { + while (p < pend && !stop) { + const char c = *p; - if ((localPart.str().length() + domainPart.str().length()) >= 256) - { + if ((localPart.str().length() + domainPart.str().length()) >= 256) { state = State_Error; break; } - switch (state) - { - case State_Before: + switch (state) { - if (parserHelpers::isSpace(c)) - ++p; - else - state = State_LocalPartStart; + case State_Before: - break; - - case State_LocalPartStart: - - if (c == '"') - { - state = State_LocalPartQuoted; - ++p; - } - else if (c == '=') - { - state = State_LocalPartRFC2047Start; - ++p; - } - else if (c == '(') - { - state = State_LocalPartComment; - ++commentLevel; - ++p; - } - else - { - state = State_LocalPartMiddle; - localPart << c; - ++p; - } - - break; - - case State_LocalPartComment: - - if (escapeNext) - { - escapeNext = false; - ++p; - } - else if (c == '\\') - { - escapeNext = true; - ++p; - } - else if (c == '(') - { - ++commentLevel; - ++p; - } - else if (c == ')') - { - if (--commentLevel == 0) - { - // End of comment - state = State_LocalPartMiddle; + if (parserHelpers::isSpace(c)) { + ++p; + } else { + state = State_LocalPartStart; } - ++p; - } - else - { - // Comment continues - ++p; - } + break; - break; + case State_LocalPartStart: - case State_LocalPartQuoted: + if (c == '"') { - if (escapeNext) - { - escapeNext = false; + state = State_LocalPartQuoted; + ++p; - if (c == '"' || c == '\\') - { + } else if (c == '=') { + + state = State_LocalPartRFC2047Start; + ++p; + + } else if (c == '(') { + + state = State_LocalPartComment; + ++commentLevel; + ++p; + + } else { + + state = State_LocalPartMiddle; localPart << c; ++p; } - else - { - // This char cannot be escaped - state = State_Error; + + break; + + case State_LocalPartComment: + + if (escapeNext) { + + escapeNext = false; + ++p; + + } else if (c == '\\') { + + escapeNext = true; + ++p; + + } else if (c == '(') { + + ++commentLevel; + ++p; + + } else if (c == ')') { + + if (--commentLevel == 0) { + // End of comment + state = State_LocalPartMiddle; + } + + ++p; + + } else { + + // Comment continues + ++p; } - } - else if (c == '"') - { - // End of quoted string - state = State_LocalPartMiddle; - ++p; - } - else if (c == '\\') - { - escapeNext = true; - ++p; - } - else - { - localPart << c; - ++p; - } - break; + break; - case State_LocalPartRFC2047Start: + case State_LocalPartQuoted: - if (c == '?') - { - state = State_LocalPartRFC2047Middle; - localPart << "=?"; - localPartIsRFC2047 = true; - ++p; - } - else - { - state = State_LocalPartMiddle; - localPart << '='; - localPart << c; - ++p; - } + if (escapeNext) { - break; + escapeNext = false; - case State_LocalPartMiddle: + if (c == '"' || c == '\\') { - if (c == '.') - { - prevIsDot = true; - localPart << c; - ++p; - } - else if (c == '"' && prevIsDot) - { - prevIsDot = false; - state = State_LocalPartQuoted; - ++p; - } - else if (c == '(') - { - // By allowing comments anywhere in the local part, - // we are more permissive than RFC-2822 - state = State_LocalPartComment; - ++commentLevel; - ++p; - } - else if (c == '@') - { - atFound = true; - state = State_DomainPartStart; - ++p; - } - else if (parserHelpers::isSpace(c)) - { - // Allow not specifying domain part - state = State_End; - } - else - { - prevIsDot = false; - localPart << c; - ++p; - } + localPart << c; + ++p; - break; + } else { - case State_LocalPartRFC2047Middle: + // This char cannot be escaped + state = State_Error; + } - if (c == '?') - { - state = State_LocalPartRFC2047MiddleQM; - ++p; - } - else - { - localPart << c; - ++p; - } + } else if (c == '"') { - break; + // End of quoted string + state = State_LocalPartMiddle; + ++p; - case State_LocalPartRFC2047MiddleQM: + } else if (c == '\\') { - if (c == '=') - { - // End of RFC-2047 encoded word - state = State_LocalPartRFC2047End; - localPart << "?="; - ++p; - } - else - { - state = State_LocalPartRFC2047Middle; - localPart << '?'; - localPart << c; - ++p; - } + escapeNext = true; + ++p; - break; + } else { - case State_LocalPartRFC2047End: + localPart << c; + ++p; + } - if (c == '@') - { - atFound = true; - state = State_DomainPartStart; - ++p; - } - else - { - state = State_End; - } + break; - break; + case State_LocalPartRFC2047Start: - case State_DomainPartStart: + if (c == '?') { - if (c == '(') - { - state = State_DomainPartComment; - ++commentLevel; - ++p; - } - else - { - state = State_DomainPartMiddle; - domainPart << c; - ++p; - } + state = State_LocalPartRFC2047Middle; + localPart << "=?"; + localPartIsRFC2047 = true; + ++p; - break; + } else { - case State_DomainPartMiddle: + state = State_LocalPartMiddle; + localPart << '='; + localPart << c; + ++p; + } - if (parserHelpers::isSpace(c)) - { - state = State_End; - } - else if (c == '(') - { - // By allowing comments anywhere in the domain part, - // we are more permissive than RFC-2822 - state = State_DomainPartComment; - ++commentLevel; - ++p; - } - else - { - domainPart << c; - ++p; - } + break; - break; + case State_LocalPartMiddle: - case State_DomainPartComment: + if (c == '.') { + + prevIsDot = true; + localPart << c; + ++p; + + } else if (c == '"' && prevIsDot) { + + prevIsDot = false; + state = State_LocalPartQuoted; + ++p; + + } else if (c == '(') { + + // By allowing comments anywhere in the local part, + // we are more permissive than RFC-2822 + state = State_LocalPartComment; + ++commentLevel; + ++p; + + } else if (c == '@') { + + atFound = true; + state = State_DomainPartStart; + ++p; + + } else if (parserHelpers::isSpace(c)) { + + // Allow not specifying domain part + state = State_End; + + } else { + + prevIsDot = false; + localPart << c; + ++p; + } + + break; + + case State_LocalPartRFC2047Middle: + + if (c == '?') { + + state = State_LocalPartRFC2047MiddleQM; + ++p; + + } else { + + localPart << c; + ++p; + } + + break; + + case State_LocalPartRFC2047MiddleQM: + + if (c == '=') { + + // End of RFC-2047 encoded word + state = State_LocalPartRFC2047End; + localPart << "?="; + ++p; + + } else { + + state = State_LocalPartRFC2047Middle; + localPart << '?'; + localPart << c; + ++p; + } + + break; + + case State_LocalPartRFC2047End: + + if (c == '@') { + + atFound = true; + state = State_DomainPartStart; + ++p; + + } else { + + state = State_End; + } + + break; + + case State_DomainPartStart: + + if (c == '(') { + + state = State_DomainPartComment; + ++commentLevel; + ++p; + + } else { - if (escapeNext) - { - escapeNext = false; - ++p; - } - else if (c == '\\') - { - escapeNext = true; - ++p; - } - else if (c == '(') - { - ++commentLevel; - ++p; - } - else if (c == ')') - { - if (--commentLevel == 0) - { - // End of comment state = State_DomainPartMiddle; + domainPart << c; + ++p; } - ++p; - } - else - { - // Comment continues - ++p; - } + break; - break; + case State_DomainPartMiddle: - case State_End: - case State_Error: + if (parserHelpers::isSpace(c)) { - stop = true; - break; + state = State_End; + + } else if (c == '(') { + + // By allowing comments anywhere in the domain part, + // we are more permissive than RFC-2822 + state = State_DomainPartComment; + ++commentLevel; + ++p; + + } else { + + domainPart << c; + ++p; + } + + break; + + case State_DomainPartComment: + + if (escapeNext) { + + escapeNext = false; + ++p; + + } else if (c == '\\') { + + escapeNext = true; + ++p; + + } else if (c == '(') { + + ++commentLevel; + ++p; + + } else if (c == ')') { + + if (--commentLevel == 0) { + + // End of comment + state = State_DomainPartMiddle; + } + + ++p; + + } else { + + // Comment continues + ++p; + } + + break; + + case State_End: + case State_Error: + + stop = true; + break; } } - if (p == pend && state != State_Error) - { - if (state == State_DomainPartMiddle) + if (p == pend && state != State_Error) { + + if (state == State_DomainPartMiddle) { state = State_End; - else if (state == State_LocalPartMiddle) + } else if (state == State_LocalPartMiddle) { state = State_End; // allow not specifying domain part + } } - if (state != State_End) - { + if (state != State_End) { + m_localName = word("invalid", vmime::charsets::UTF_8); m_domainName = word("invalid", vmime::charsets::UTF_8); - } - else - { - // If the domain part is missing, use local host name - if (domainPart.str().empty() && !atFound) - domainPart << platform::getHandler()->getHostName(); - if (localPartIsRFC2047) + } else { + + // If the domain part is missing, use local host name + if (domainPart.str().empty() && !atFound) { + domainPart << platform::getHandler()->getHostName(); + } + + if (localPartIsRFC2047) { m_localName.parse(localPart.str()); - else + } else { m_localName = word(localPart.str(), vmime::charsets::UTF_8); + } m_domainName = word(domainNameFromIDNA(domainPart.str()), vmime::charsets::UTF_8); } setParsedBounds(position, p - pend); - if (newPosition) + if (newPosition) { *newPosition = p - pend; + } } -void emailAddress::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void emailAddress::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + string localPart, domainPart; if (ctx.getInternationalizedEmailSupport() && (!utility::stringUtils::is7bit(m_localName.getBuffer()) || - !utility::stringUtils::is7bit(m_domainName.getBuffer()))) - { + !utility::stringUtils::is7bit(m_domainName.getBuffer()))) { + // Local part string localPartUTF8(m_localName.getConvertedText(vmime::charsets::UTF_8)); word localPartWord(localPartUTF8, vmime::charsets::UTF_8); @@ -563,9 +584,9 @@ void emailAddress::generateImpl // Domain part domainPart = m_domainName.getConvertedText(vmime::charsets::UTF_8); - } - else - { + + } else { + // Local part vmime::utility::outputStreamStringAdapter os(localPart); m_localName.generate(ctx, os, 0, NULL, text::QUOTE_IF_NEEDED, NULL); @@ -578,8 +599,8 @@ void emailAddress::generateImpl << "@" << domainPart; - if (newLinePos) - { + if (newLinePos) { + *newLinePos = curLinePos + localPart.length() + 1 // @ @@ -588,21 +609,21 @@ void emailAddress::generateImpl } -bool emailAddress::operator==(const class emailAddress& eml) const -{ - return (m_localName == eml.m_localName && - m_domainName == eml.m_domainName); +bool emailAddress::operator==(const class emailAddress& eml) const { + + return m_localName == eml.m_localName && + m_domainName == eml.m_domainName; } -bool emailAddress::operator!=(const class emailAddress& eml) const -{ +bool emailAddress::operator!=(const class emailAddress& eml) const { + return !(*this == eml); } -void emailAddress::copyFrom(const component& other) -{ +void emailAddress::copyFrom(const component& other) { + const emailAddress& source = dynamic_cast (other); m_localName = source.m_localName; @@ -610,57 +631,57 @@ void emailAddress::copyFrom(const component& other) } -emailAddress& emailAddress::operator=(const emailAddress& other) -{ +emailAddress& emailAddress::operator=(const emailAddress& other) { + copyFrom(other); - return (*this); + return *this; } -shared_ptr emailAddress::clone() const -{ +shared_ptr emailAddress::clone() const { + return make_shared (*this); } -const word& emailAddress::getLocalName() const -{ +const word& emailAddress::getLocalName() const { + return m_localName; } -void emailAddress::setLocalName(const word& localName) -{ +void emailAddress::setLocalName(const word& localName) { + m_localName = localName; } -const word& emailAddress::getDomainName() const -{ +const word& emailAddress::getDomainName() const { + return m_domainName; } -void emailAddress::setDomainName(const word& domainName) -{ +void emailAddress::setDomainName(const word& domainName) { + m_domainName = domainName; } -const std::vector > emailAddress::getChildComponents() -{ +const std::vector > emailAddress::getChildComponents() { + return std::vector >(); } -bool emailAddress::isEmpty() const -{ +bool emailAddress::isEmpty() const { + return m_localName.isEmpty(); } -const string emailAddress::toString() const -{ +const string emailAddress::toString() const { + std::ostringstream oss; utility::outputStreamAdapter adapter(oss); @@ -673,8 +694,8 @@ const string emailAddress::toString() const } -const text emailAddress::toText() const -{ +const text emailAddress::toText() const { + text txt; txt.appendWord(make_shared (m_localName)); txt.appendWord(make_shared ("@", vmime::charsets::US_ASCII)); diff --git a/src/vmime/emailAddress.hpp b/src/vmime/emailAddress.hpp index 30ee24ab..78249967 100644 --- a/src/vmime/emailAddress.hpp +++ b/src/vmime/emailAddress.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/text.hpp" -namespace vmime -{ +namespace vmime { /** An email address: local name and domain name (basic type). */ +class VMIME_EXPORT emailAddress : public component { -class VMIME_EXPORT emailAddress : public component -{ public: emailAddress(); @@ -114,18 +112,20 @@ public: using component::generate; // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/emptyContentHandler.cpp b/src/vmime/emptyContentHandler.cpp index e0f191f3..3cf7965b 100644 --- a/src/vmime/emptyContentHandler.cpp +++ b/src/vmime/emptyContentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,92 +24,101 @@ #include "vmime/emptyContentHandler.hpp" -namespace vmime -{ +namespace vmime { -emptyContentHandler::emptyContentHandler() -{ +emptyContentHandler::emptyContentHandler() { + } -shared_ptr emptyContentHandler::clone() const -{ +shared_ptr emptyContentHandler::clone() const { + return make_shared (); } -void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime::encoding& /* enc */, - const size_t /* maxLineLength */) const -{ +void emptyContentHandler::generate( + utility::outputStream& /* os */, + const vmime::encoding& /* enc */, + const size_t /* maxLineLength */ +) const { + // Nothing to do. } -void emptyContentHandler::extract(utility::outputStream& /* os */, +void emptyContentHandler::extract( + utility::outputStream& /* os */, utility::progressListener* progress) const { - if (progress) + if (progress) { progress->start(0); + } // Nothing to do. - if (progress) + if (progress) { progress->stop(0); + } } -void emptyContentHandler::extractRaw(utility::outputStream& /* os */, - utility::progressListener* progress) const -{ - if (progress) +void emptyContentHandler::extractRaw( + utility::outputStream& /* os */, + utility::progressListener* progress +) const { + + if (progress) { progress->start(0); + } // Nothing to do. - if (progress) + if (progress) { progress->stop(0); + } } -size_t emptyContentHandler::getLength() const -{ - return (0); +size_t emptyContentHandler::getLength() const { + + return 0; } -bool emptyContentHandler::isEmpty() const -{ - return (true); -} +bool emptyContentHandler::isEmpty() const { - -bool emptyContentHandler::isEncoded() const -{ - return (false); -} - - -const vmime::encoding& emptyContentHandler::getEncoding() const -{ - return (NO_ENCODING); -} - - -bool emptyContentHandler::isBuffered() const -{ return true; } -void emptyContentHandler::setContentTypeHint(const mediaType& type) -{ +bool emptyContentHandler::isEncoded() const { + + return false; +} + + +const vmime::encoding& emptyContentHandler::getEncoding() const { + + return NO_ENCODING; +} + + +bool emptyContentHandler::isBuffered() const { + + return true; +} + + +void emptyContentHandler::setContentTypeHint(const mediaType& type) { + m_contentType = type; } -const mediaType emptyContentHandler::getContentTypeHint() const -{ +const mediaType emptyContentHandler::getContentTypeHint() const { + return m_contentType; } diff --git a/src/vmime/emptyContentHandler.hpp b/src/vmime/emptyContentHandler.hpp index 369a4206..b7e08978 100644 --- a/src/vmime/emptyContentHandler.hpp +++ b/src/vmime/emptyContentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,22 +28,32 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { -class VMIME_EXPORT emptyContentHandler : public contentHandler -{ +class VMIME_EXPORT emptyContentHandler : public contentHandler { + public: emptyContentHandler(); shared_ptr clone() const; - void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + void generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength = lineLengthLimits::infinite + ) const; - void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; - void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL + ) const; + + void extractRaw( + utility::outputStream& os, + utility::progressListener* progress = NULL + ) const; size_t getLength() const; diff --git a/src/vmime/encoding.cpp b/src/vmime/encoding.cpp index 649bee79..23814a67 100644 --- a/src/vmime/encoding.cpp +++ b/src/vmime/encoding.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,118 +30,140 @@ #include -namespace vmime -{ +namespace vmime { encoding::encoding() : m_name(encodingTypes::SEVEN_BIT), - m_usage(USAGE_UNKNOWN) -{ + m_usage(USAGE_UNKNOWN) { + } encoding::encoding(const string& name) : m_name(utility::stringUtils::toLower(name)), - m_usage(USAGE_UNKNOWN) -{ + m_usage(USAGE_UNKNOWN) { + } encoding::encoding(const string& name, const EncodingUsage usage) : m_name(utility::stringUtils::toLower(name)), - m_usage(usage) -{ + m_usage(usage) { + } encoding::encoding(const encoding& enc) - : headerFieldValue(), m_name(enc.m_name), m_usage(enc.m_usage) -{ + : headerFieldValue(), + m_name(enc.m_name), + m_usage(enc.m_usage) { } -void encoding::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void encoding::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_usage = USAGE_UNKNOWN; - m_name = utility::stringUtils::toLower(utility::stringUtils::trim - (utility::stringUtils::unquote(utility::stringUtils::trim - (string(buffer.begin() + position, buffer.begin() + end))))); + m_name = utility::stringUtils::toLower( + utility::stringUtils::trim( + utility::stringUtils::unquote( + utility::stringUtils::trim( + string(buffer.begin() + position, buffer.begin() + end) + ) + ) + ) + ); - if (m_name.empty()) + if (m_name.empty()) { m_name = encodingTypes::SEVEN_BIT; // assume default "7-bit" + } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void encoding::generateImpl - (const generationContext& /* ctx */, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void encoding::generateImpl( + const generationContext& /* ctx */, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + os << m_name; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + m_name.length(); + } } -shared_ptr encoding::getEncoder() const -{ +shared_ptr encoding::getEncoder() const { + shared_ptr encoder = utility::encoder::encoderFactory::getInstance()->create(generate()); // FIXME: this should not be here (move me into QP encoder instead?) - if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE) + if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE) { encoder->getProperties()["text"] = true; + } return encoder; } -encoding& encoding::operator=(const encoding& other) -{ +encoding& encoding::operator=(const encoding& other) { + copyFrom(other); return (*this); } -encoding& encoding::operator=(const string& name) -{ +encoding& encoding::operator=(const string& name) { + m_name = utility::stringUtils::toLower(name); m_usage = USAGE_UNKNOWN; - return (*this); + + return *this; } -bool encoding::operator==(const encoding& value) const -{ - return (utility::stringUtils::toLower(m_name) == value.m_name); +bool encoding::operator==(const encoding& value) const { + + return utility::stringUtils::toLower(m_name) == value.m_name; } -bool encoding::operator!=(const encoding& value) const -{ +bool encoding::operator!=(const encoding& value) const { + return !(*this == value); } -const encoding encoding::decideImpl - (const string::const_iterator begin, const string::const_iterator end) -{ +const encoding encoding::decideImpl( + const string::const_iterator begin, + const string::const_iterator end +) { + const string::difference_type length = end - begin; - const string::difference_type count = std::count_if - (begin, end, std::bind2nd(std::less(), 127)); + const string::difference_type count = std::count_if( + begin, end, + std::bind2nd(std::less(), 127) + ); // All is in 7-bit US-ASCII --> 7-bit (or Quoted-Printable...) - if (length == count) - { + if (length == count) { + // Now, we check if there is any line with more than // "lineLengthLimits::convenient" characters (7-bit requires that) string::const_iterator p = begin; @@ -149,49 +171,51 @@ const encoding encoding::decideImpl const size_t maxLen = lineLengthLimits::convenient; size_t len = 0; - for ( ; p != end && len <= maxLen ; ) - { - if (*p == '\n') - { + for ( ; p != end && len <= maxLen ; ) { + + if (*p == '\n') { + len = 0; ++p; // May or may not need to be encoded, we don't take // any risk (avoid problems with SMTP) - if (p != end && *p == '.') + if (p != end && *p == '.') { len = maxLen + 1; - } - else - { + } + + } else { + ++len; ++p; } } - if (len > maxLen) - return (encoding(encodingTypes::QUOTED_PRINTABLE)); - else - return (encoding(encodingTypes::SEVEN_BIT)); - } + if (len > maxLen) { + return encoding(encodingTypes::QUOTED_PRINTABLE); + } else { + return encoding(encodingTypes::SEVEN_BIT); + } + // Less than 20% non US-ASCII --> Quoted-Printable - else if ((length - count) <= length / 5) - { - return (encoding(encodingTypes::QUOTED_PRINTABLE)); - } + } else if ((length - count) <= length / 5) { + + return encoding(encodingTypes::QUOTED_PRINTABLE); + // Otherwise --> Base64 - else - { - return (encoding(encodingTypes::BASE64)); + } else { + + return encoding(encodingTypes::BASE64); } } -bool encoding::shouldReencode() const -{ +bool encoding::shouldReencode() const { + if (m_name == encodingTypes::BASE64 || m_name == encodingTypes::QUOTED_PRINTABLE || - m_name == encodingTypes::UUENCODE) - { + m_name == encodingTypes::UUENCODE) { + return false; } @@ -199,18 +223,21 @@ bool encoding::shouldReencode() const } -const encoding encoding::decide - (const shared_ptr & data, const EncodingUsage usage) -{ +const encoding encoding::decide( + const shared_ptr & data, + const EncodingUsage usage +) { + // Do not re-encode data if it is already encoded - if (data->isEncoded() && !data->getEncoding().shouldReencode()) + if (data->isEncoded() && !data->getEncoding().shouldReencode()) { return data->getEncoding(); + } encoding enc; if (usage == USAGE_TEXT && data->isBuffered() && - data->getLength() > 0 && data->getLength() < 32768) - { + data->getLength() > 0 && data->getLength() < 32768) { + // Extract data into temporary buffer string buffer; utility::outputStreamStringAdapter os(buffer); @@ -219,9 +246,9 @@ const encoding encoding::decide os.flush(); enc = decideImpl(buffer.begin(), buffer.end()); - } - else - { + + } else { + enc = encoding(encodingTypes::BASE64); } @@ -231,19 +258,23 @@ const encoding encoding::decide } -const encoding encoding::decide(const shared_ptr & data, - const charset& chset, const EncodingUsage usage) -{ - // Do not re-encode data if it is already encoded - if (data->isEncoded() && !data->getEncoding().shouldReencode()) - return data->getEncoding(); +const encoding encoding::decide( + const shared_ptr & data, + const charset& chset, + const EncodingUsage usage +) { + + // Do not re-encode data if it is already encoded + if (data->isEncoded() && !data->getEncoding().shouldReencode()) { + return data->getEncoding(); + } + + if (usage == USAGE_TEXT) { - if (usage == USAGE_TEXT) - { encoding recEncoding; - if (chset.getRecommendedEncoding(recEncoding)) - { + if (chset.getRecommendedEncoding(recEncoding)) { + recEncoding.setUsage(usage); return recEncoding; } @@ -253,46 +284,46 @@ const encoding encoding::decide(const shared_ptr & data, } -shared_ptr encoding::clone() const -{ +shared_ptr encoding::clone() const { + return make_shared (*this); } -void encoding::copyFrom(const component& other) -{ +void encoding::copyFrom(const component& other) { + const encoding& e = dynamic_cast (other); m_name = e.m_name; } -const string& encoding::getName() const -{ - return (m_name); +const string& encoding::getName() const { + + return m_name; } -void encoding::setName(const string& name) -{ +void encoding::setName(const string& name) { + m_name = name; } -encoding::EncodingUsage encoding::getUsage() const -{ +encoding::EncodingUsage encoding::getUsage() const { + return m_usage; } -void encoding::setUsage(const EncodingUsage usage) -{ +void encoding::setUsage(const EncodingUsage usage) { + m_usage = usage; } -const std::vector > encoding::getChildComponents() -{ +const std::vector > encoding::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/encoding.hpp b/src/vmime/encoding.hpp index 48973daa..2ff17ef6 100644 --- a/src/vmime/encoding.hpp +++ b/src/vmime/encoding.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,8 +31,7 @@ #include "vmime/utility/encoder/encoder.hpp" -namespace vmime -{ +namespace vmime { class contentHandler; @@ -40,13 +39,12 @@ class contentHandler; /** Content encoding (basic type). */ +class VMIME_EXPORT encoding : public headerFieldValue { -class VMIME_EXPORT encoding : public headerFieldValue -{ public: - enum EncodingUsage - { + enum EncodingUsage { + USAGE_UNKNOWN, USAGE_TEXT, /**< Use for body text. */ USAGE_BINARY_DATA /**< Use for attachment, image... */ @@ -99,7 +97,10 @@ public: * @param usage context of use of data * @return suitable encoding for specified data */ - static const encoding decide(const shared_ptr & data, const EncodingUsage usage = USAGE_BINARY_DATA); + static const encoding decide( + const shared_ptr & data, + const EncodingUsage usage = USAGE_BINARY_DATA + ); /** Decide which encoding to use based on the specified data and charset. * @@ -108,7 +109,11 @@ public: * @param usage context of use of data * @return suitable encoding for specified data and charset */ - static const encoding decide(const shared_ptr & data, const charset& chset, const EncodingUsage usage = USAGE_BINARY_DATA); + static const encoding decide( + const shared_ptr & data, + const charset& chset, + const EncodingUsage usage = USAGE_BINARY_DATA + ); shared_ptr clone() const; @@ -144,23 +149,28 @@ private: * @param end end iterator in buffer * @return suitable encoding for specified data */ - static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end); + static const encoding decideImpl( + const string::const_iterator begin, + const string::const_iterator end + ); protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/exception.cpp b/src/vmime/exception.cpp index b96b7c37..fb9dea94 100644 --- a/src/vmime/exception.cpp +++ b/src/vmime/exception.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,31 +35,31 @@ const exception exception::NO_EXCEPTION; exception::exception() - : std::runtime_error(""), m_other(NULL) -{ + : std::runtime_error(""), m_other(NULL) { + } exception::exception(const string& what, const exception& other) - : std::runtime_error(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL) -{ + : std::runtime_error(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL) { + } exception::exception(const exception& e) - : std::runtime_error(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone()) -{ + : std::runtime_error(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone()) { + } -exception::~exception() throw() -{ - delete (m_other); +exception::~exception() throw() { + + delete m_other; } -void exception::chainException(const exception& other) -{ +void exception::chainException(const exception& other) { + exception* e = other.clone(); delete m_other; @@ -67,27 +67,26 @@ void exception::chainException(const exception& other) } -const exception* exception::other() const throw() -{ - return (m_other); +const exception* exception::other() const throw() { + + return m_other; } -const char* exception::name() const throw() -{ +const char* exception::name() const throw() { + return "exception"; } -exception* exception::clone() const -{ +exception* exception::clone() const { + return new exception(*this); } -namespace exceptions -{ +namespace exceptions { // diff --git a/src/vmime/exception.hpp b/src/vmime/exception.hpp index 9dcbf641..da0ec246 100644 --- a/src/vmime/exception.hpp +++ b/src/vmime/exception.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,15 +32,13 @@ #include "vmime/utility/path.hpp" -namespace vmime -{ +namespace vmime { /** Base class for VMime exceptions. */ +class VMIME_EXPORT exception : public std::runtime_error { -class VMIME_EXPORT exception : public std::runtime_error -{ private: exception* m_other; @@ -87,13 +85,11 @@ protected: /** List of all VMime exceptions. */ - -namespace exceptions -{ +namespace exceptions { -class VMIME_EXPORT bad_field_value_type : public vmime::exception -{ +class VMIME_EXPORT bad_field_value_type : public vmime::exception { + public: bad_field_value_type(const string& fieldName, const exception& other = NO_EXCEPTION); @@ -104,8 +100,8 @@ public: }; -class VMIME_EXPORT charset_conv_error : public vmime::exception -{ +class VMIME_EXPORT charset_conv_error : public vmime::exception { + public: charset_conv_error(const string& what = "", const exception& other = NO_EXCEPTION); @@ -116,8 +112,8 @@ public: }; -class VMIME_EXPORT illegal_byte_sequence_for_charset : public vmime::exception -{ +class VMIME_EXPORT illegal_byte_sequence_for_charset : public vmime::exception { + public: illegal_byte_sequence_for_charset(const string& what = "", const exception& other = NO_EXCEPTION); @@ -130,9 +126,8 @@ public: /** No encoder has been found for the specified encoding name. */ +class VMIME_EXPORT no_encoder_available : public vmime::exception { -class VMIME_EXPORT no_encoder_available : public vmime::exception -{ public: no_encoder_available(const string& name, const exception& other = NO_EXCEPTION); @@ -145,9 +140,8 @@ public: /** No algorithm has been found for the specified name. */ +class VMIME_EXPORT no_digest_algorithm_available : public vmime::exception { -class VMIME_EXPORT no_digest_algorithm_available : public vmime::exception -{ public: no_digest_algorithm_available(const string& name, const exception& other = NO_EXCEPTION); @@ -158,8 +152,8 @@ public: }; -class VMIME_EXPORT no_such_field : public vmime::exception -{ +class VMIME_EXPORT no_such_field : public vmime::exception { + public: no_such_field(const exception& other = NO_EXCEPTION); @@ -170,8 +164,8 @@ public: }; -class VMIME_EXPORT no_such_part : public vmime::exception -{ +class VMIME_EXPORT no_such_part : public vmime::exception { + public: no_such_part(const exception& other = NO_EXCEPTION); @@ -182,8 +176,8 @@ public: }; -class VMIME_EXPORT no_such_message_id : public vmime::exception -{ +class VMIME_EXPORT no_such_message_id : public vmime::exception { + public: no_such_message_id(const exception& other = NO_EXCEPTION); @@ -194,8 +188,8 @@ public: }; -class VMIME_EXPORT open_file_error : public vmime::exception -{ +class VMIME_EXPORT open_file_error : public vmime::exception { + public: open_file_error(const exception& other = NO_EXCEPTION); @@ -206,8 +200,8 @@ public: }; -class VMIME_EXPORT no_factory_available : public vmime::exception -{ +class VMIME_EXPORT no_factory_available : public vmime::exception { + public: no_factory_available(const exception& other = NO_EXCEPTION); @@ -218,8 +212,8 @@ public: }; -class VMIME_EXPORT no_platform_handler : public vmime::exception -{ +class VMIME_EXPORT no_platform_handler : public vmime::exception { + public: no_platform_handler(const exception& other = NO_EXCEPTION); @@ -232,9 +226,8 @@ public: /** No expeditor specified. */ +class VMIME_EXPORT no_expeditor : public vmime::exception { -class VMIME_EXPORT no_expeditor : public vmime::exception -{ public: no_expeditor(const exception& other = NO_EXCEPTION); @@ -247,9 +240,8 @@ public: /** No recipient specified. */ +class VMIME_EXPORT no_recipient : public vmime::exception { -class VMIME_EXPORT no_recipient : public vmime::exception -{ public: no_recipient(const exception& other = NO_EXCEPTION); @@ -262,9 +254,8 @@ public: /** There is no property with that name in the set. */ +class VMIME_EXPORT no_such_property : public vmime::exception { -class VMIME_EXPORT no_such_property : public vmime::exception -{ public: no_such_property(const string& name, const exception& other = NO_EXCEPTION); @@ -277,9 +268,8 @@ public: /** Bad type specified when reading property. */ +class VMIME_EXPORT invalid_property_type : public vmime::exception { -class VMIME_EXPORT invalid_property_type : public vmime::exception -{ public: invalid_property_type(const exception& other = NO_EXCEPTION); @@ -292,9 +282,8 @@ public: /** Bad argument was passed to the function. */ +class VMIME_EXPORT invalid_argument : public vmime::exception { -class VMIME_EXPORT invalid_argument : public vmime::exception -{ public: invalid_argument(const exception& other = NO_EXCEPTION); @@ -307,9 +296,8 @@ public: /** Underlying operating system error. */ +class VMIME_EXPORT system_error : public vmime::exception { -class VMIME_EXPORT system_error : public vmime::exception -{ public: system_error(const string& what, const exception& other = NO_EXCEPTION); @@ -322,9 +310,8 @@ public: /** The URL is malformed. */ +class VMIME_EXPORT malformed_url : public vmime::exception { -class VMIME_EXPORT malformed_url : public vmime::exception -{ public: malformed_url(const string& error, const exception& other = NO_EXCEPTION); @@ -341,9 +328,8 @@ public: /** Base class for exceptions thrown by the networking module. */ +class VMIME_EXPORT net_exception : public vmime::exception { -class VMIME_EXPORT net_exception : public vmime::exception -{ public: net_exception(const string& what, const exception& other = NO_EXCEPTION); @@ -362,9 +348,8 @@ typedef net_exception messaging_exception; /** Socket error. */ +class VMIME_EXPORT socket_exception : public net_exception { -class VMIME_EXPORT socket_exception : public net_exception -{ public: socket_exception(const string& what = "", const exception& other = NO_EXCEPTION); @@ -379,9 +364,8 @@ public: /** Socket not connected: you are trying to write to/read from a socket which * is not connected to a peer. */ +class VMIME_EXPORT socket_not_connected_exception : public socket_exception { -class VMIME_EXPORT socket_not_connected_exception : public socket_exception -{ public: socket_not_connected_exception(const string& what = "", const exception& other = NO_EXCEPTION); @@ -396,9 +380,8 @@ public: /** Error while connecting to the server: this may be a DNS resolution error * or a connection error (for example, time-out while connecting). */ +class VMIME_EXPORT connection_error : public socket_exception { -class VMIME_EXPORT connection_error : public socket_exception -{ public: connection_error(const string& what = "", const exception& other = NO_EXCEPTION); @@ -411,9 +394,8 @@ public: /** Server did not initiated the connection correctly. */ +class VMIME_EXPORT connection_greeting_error : public net_exception { -class VMIME_EXPORT connection_greeting_error : public net_exception -{ public: connection_greeting_error(const string& response, const exception& other = NO_EXCEPTION); @@ -433,9 +415,8 @@ private: /** Error while giving credentials to the server (wrong username * or password, or wrong authentication method). */ +class VMIME_EXPORT authentication_error : public net_exception { -class VMIME_EXPORT authentication_error : public net_exception -{ public: authentication_error(const string& response, const exception& other = NO_EXCEPTION); @@ -454,9 +435,8 @@ private: /** Option not supported. */ +class VMIME_EXPORT unsupported_option : public net_exception { -class VMIME_EXPORT unsupported_option : public net_exception -{ public: unsupported_option(const exception& other = NO_EXCEPTION); @@ -470,9 +450,8 @@ public: /** The current state of the object does not permit to execute the * operation (for example, you try to close a folder which is not open). */ +class VMIME_EXPORT illegal_state : public net_exception { -class VMIME_EXPORT illegal_state : public net_exception -{ public: illegal_state(const string& state, const exception& other = NO_EXCEPTION); @@ -485,9 +464,8 @@ public: /** Folder not found (does not exist). */ +class VMIME_EXPORT folder_not_found : public net_exception { -class VMIME_EXPORT folder_not_found : public net_exception -{ public: folder_not_found(const exception& other = NO_EXCEPTION); @@ -500,9 +478,8 @@ public: /** Folder is already open in the same session. */ +class VMIME_EXPORT folder_already_open : public net_exception { -class VMIME_EXPORT folder_already_open : public net_exception -{ public: folder_already_open(const exception& other = NO_EXCEPTION); @@ -515,9 +492,8 @@ public: /** Message not found (does not exist). */ +class VMIME_EXPORT message_not_found : public net_exception { -class VMIME_EXPORT message_not_found : public net_exception -{ public: message_not_found(const exception& other = NO_EXCEPTION); @@ -530,9 +506,8 @@ public: /** Operation not supported by the underlying protocol. */ +class VMIME_EXPORT operation_not_supported : public net_exception { -class VMIME_EXPORT operation_not_supported : public net_exception -{ public: operation_not_supported(const exception& other = NO_EXCEPTION); @@ -545,9 +520,8 @@ public: /** The operation timed out (time-out delay is elapsed). */ +class VMIME_EXPORT operation_timed_out : public net_exception { -class VMIME_EXPORT operation_timed_out : public net_exception -{ public: operation_timed_out(const exception& other = NO_EXCEPTION); @@ -560,9 +534,8 @@ public: /** The operation has been cancelled. */ +class VMIME_EXPORT operation_cancelled : public net_exception { -class VMIME_EXPORT operation_cancelled : public net_exception -{ public: operation_cancelled(const exception& other = NO_EXCEPTION); @@ -576,9 +549,8 @@ public: /** Must call fetchMessage() or fetchHeader() before accessing * the requested object. */ +class VMIME_EXPORT unfetched_object : public net_exception { -class VMIME_EXPORT unfetched_object : public net_exception -{ public: unfetched_object(const exception& other = NO_EXCEPTION); @@ -591,9 +563,8 @@ public: /** The service is not currently connected. */ +class VMIME_EXPORT not_connected : public net_exception { -class VMIME_EXPORT not_connected : public net_exception -{ public: not_connected(const exception& other = NO_EXCEPTION); @@ -606,9 +577,8 @@ public: /** The service is already connected (must disconnect before). */ +class VMIME_EXPORT already_connected : public net_exception { -class VMIME_EXPORT already_connected : public net_exception -{ public: already_connected(const exception& other = NO_EXCEPTION); @@ -621,9 +591,8 @@ public: /** Illegal operation: cannot run this operation on the object. */ +class VMIME_EXPORT illegal_operation : public net_exception { -class VMIME_EXPORT illegal_operation : public net_exception -{ public: illegal_operation(const string& msg = "", const exception& other = NO_EXCEPTION); @@ -636,12 +605,17 @@ public: /** Command error: operation failed (this is specific to the underlying protocol). */ +class VMIME_EXPORT command_error : public net_exception { -class VMIME_EXPORT command_error : public net_exception -{ public: - command_error(const string& command, const string& response, const string& desc = "", const exception& other = NO_EXCEPTION); + command_error( + const string& command, + const string& response, + const string& desc = "", + const exception& other = NO_EXCEPTION + ); + ~command_error() throw(); /** Return the name of the command which have thrown the exception. @@ -670,12 +644,16 @@ private: /** The server returned an invalid response. */ +class VMIME_EXPORT invalid_response : public net_exception { -class VMIME_EXPORT invalid_response : public net_exception -{ public: - invalid_response(const string& command, const string& response, const exception& other = NO_EXCEPTION); + invalid_response( + const string& command, + const string& response, + const exception& other = NO_EXCEPTION + ); + ~invalid_response() throw(); /** Return the name of the command which have thrown the exception. @@ -704,9 +682,8 @@ private: /** Partial fetch is not supported by the underlying protocol. */ +class VMIME_EXPORT partial_fetch_not_supported : public net_exception { -class VMIME_EXPORT partial_fetch_not_supported : public net_exception -{ public: partial_fetch_not_supported(const exception& other = NO_EXCEPTION); @@ -719,9 +696,8 @@ public: /** Folder name is invalid. */ +class VMIME_EXPORT invalid_folder_name : public net_exception { -class VMIME_EXPORT invalid_folder_name : public net_exception -{ public: invalid_folder_name(const string& error = "", const exception& other = NO_EXCEPTION); @@ -740,12 +716,16 @@ public: /** Base class for exceptions thrown by the filesystem features. */ +class VMIME_EXPORT filesystem_exception : public vmime::exception { -class VMIME_EXPORT filesystem_exception : public vmime::exception -{ public: - filesystem_exception(const string& what, const utility::path& path, const exception& other = NO_EXCEPTION); + filesystem_exception( + const string& what, + const utility::path& path, + const exception& other = NO_EXCEPTION + ); + ~filesystem_exception() throw(); /** Return the full path of the file have thrown the exception. @@ -765,9 +745,8 @@ private: /** File is not a directory. */ +class VMIME_EXPORT not_a_directory : public filesystem_exception { -class VMIME_EXPORT not_a_directory : public filesystem_exception -{ public: not_a_directory(const utility::path& path, const exception& other = NO_EXCEPTION); @@ -780,9 +759,8 @@ public: /** File not found. */ +class VMIME_EXPORT file_not_found : public filesystem_exception { -class VMIME_EXPORT file_not_found : public filesystem_exception -{ public: file_not_found(const utility::path& path, const exception& other = NO_EXCEPTION); @@ -798,9 +776,8 @@ public: /** Authentication exception. */ +class VMIME_EXPORT authentication_exception : public vmime::exception { -class VMIME_EXPORT authentication_exception : public vmime::exception -{ public: authentication_exception(const string& what, const exception& other = NO_EXCEPTION); @@ -813,9 +790,8 @@ public: /** The requested information cannot be provided. */ +class VMIME_EXPORT no_auth_information : public authentication_exception { -class VMIME_EXPORT no_auth_information : public authentication_exception -{ public: no_auth_information(const exception& other = NO_EXCEPTION); @@ -831,9 +807,8 @@ public: /** Base class for exceptions thrown by SASL module. */ +class VMIME_EXPORT sasl_exception : public authentication_exception { -class VMIME_EXPORT sasl_exception : public authentication_exception -{ public: sasl_exception(const string& what, const exception& other = NO_EXCEPTION); @@ -846,9 +821,8 @@ public: /** No mechanism is registered with the specified name. */ +class VMIME_EXPORT no_such_mechanism : public sasl_exception { -class VMIME_EXPORT no_such_mechanism : public sasl_exception -{ public: no_such_mechanism(const string& name, const exception& other = NO_EXCEPTION); @@ -867,9 +841,8 @@ public: /** Base class for exceptions thrown by TLS module. */ +class VMIME_EXPORT tls_exception : public vmime::exception { -class VMIME_EXPORT tls_exception : public vmime::exception -{ public: tls_exception(const string& what, const exception& other = NO_EXCEPTION); @@ -883,7 +856,6 @@ public: #endif // VMIME_HAVE_TLS_SUPPORT - } // exceptions diff --git a/src/vmime/export.hpp b/src/vmime/export.hpp index 90f0cc3a..a3b4dfbe 100644 --- a/src/vmime/export.hpp +++ b/src/vmime/export.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/fileAttachment.cpp b/src/vmime/fileAttachment.cpp index f1697519..ac755708 100644 --- a/src/vmime/fileAttachment.cpp +++ b/src/vmime/fileAttachment.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,12 +42,14 @@ #include "vmime/utility/file.hpp" -namespace vmime -{ +namespace vmime { -fileAttachment::fileAttachment(const string& filepath, const mediaType& type) -{ +fileAttachment::fileAttachment( + const string& filepath, + const mediaType& type +) { + m_type = type; setData(filepath); @@ -56,8 +58,12 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type) } -fileAttachment::fileAttachment(const string& filepath, const mediaType& type, const text& desc) -{ +fileAttachment::fileAttachment( + const string& filepath, + const mediaType& type, + const text& desc +) { + m_type = type; m_desc = desc; @@ -67,9 +73,13 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type, co } -fileAttachment::fileAttachment(const string& filepath, const mediaType& type, - const text& desc, const encoding& enc) -{ +fileAttachment::fileAttachment( + const string& filepath, + const mediaType& type, + const text& desc, + const encoding& enc +) { + m_type = type; m_desc = desc; @@ -79,10 +89,14 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type, } -fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type) -{ - if (!filename.isEmpty()) +fileAttachment::fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type) { + + if (!filename.isEmpty()) { m_fileInfo.setFilename(filename); + } m_type = type; @@ -92,11 +106,16 @@ fileAttachment::fileAttachment(const shared_ptr & cts, const wor } -fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, - const mediaType& type, const text& desc) -{ - if (!filename.isEmpty()) +fileAttachment::fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type, + const text& desc +) { + + if (!filename.isEmpty()) { m_fileInfo.setFilename(filename); + } m_type = type; m_desc = desc; @@ -107,11 +126,17 @@ fileAttachment::fileAttachment(const shared_ptr & cts, const wor } -fileAttachment::fileAttachment(const shared_ptr & cts, const word& filename, - const mediaType& type, const text& desc, const encoding& enc) -{ - if (!filename.isEmpty()) +fileAttachment::fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type, + const text& desc, + const encoding& enc +) { + + if (!filename.isEmpty()) { m_fileInfo.setFilename(filename); + } m_type = type; m_desc = desc; @@ -121,34 +146,36 @@ fileAttachment::fileAttachment(const shared_ptr & cts, const wor } -void fileAttachment::setData(const string& filepath) -{ +void fileAttachment::setData(const string& filepath) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path path = fsf->stringToPath(filepath); shared_ptr file = fsf->create(path); - if (!file->isFile()) + if (!file->isFile()) { throw exceptions::open_file_error(); + } - m_data = make_shared - (file->getFileReader()->getInputStream(), file->getLength()); + m_data = make_shared ( + file->getFileReader()->getInputStream(), file->getLength() + ); m_fileInfo.setFilename(path.getLastComponent()); m_fileInfo.setSize(file->getLength()); } -void fileAttachment::setData(const shared_ptr & cts) -{ +void fileAttachment::setData(const shared_ptr & cts) { + m_data = cts; m_fileInfo.setSize(cts->getLength()); } -void fileAttachment::generatePart(const shared_ptr & part) const -{ +void fileAttachment::generatePart(const shared_ptr & part) const { + defaultAttachment::generatePart(part); shared_ptr cdf = @@ -162,14 +189,14 @@ void fileAttachment::generatePart(const shared_ptr & part) const } -const fileAttachment::fileInfo& fileAttachment::getFileInfo() const -{ +const fileAttachment::fileInfo& fileAttachment::getFileInfo() const { + return m_fileInfo; } -fileAttachment::fileInfo& fileAttachment::getFileInfo() -{ +fileAttachment::fileInfo& fileAttachment::getFileInfo() { + return m_fileInfo; } @@ -180,39 +207,43 @@ fileAttachment::fileInfo& fileAttachment::getFileInfo() // fileAttachment::fileInfo::fileInfo() - : m_filename(NULL), m_size(NULL), m_creationDate(NULL), m_modifDate(NULL), m_readDate(NULL) -{ + : m_filename(NULL), + m_size(NULL), + m_creationDate(NULL), + m_modifDate(NULL), + m_readDate(NULL) { + } fileAttachment::fileInfo::~fileInfo() { - delete (m_filename); - delete (m_size); - delete (m_creationDate); - delete (m_modifDate); - delete (m_readDate); + delete m_filename; + delete m_size; + delete m_creationDate; + delete m_modifDate; + delete m_readDate; } -bool fileAttachment::fileInfo::hasFilename() const { return (m_filename != NULL); } -const word& fileAttachment::fileInfo::getFilename() const { return (*m_filename); } +bool fileAttachment::fileInfo::hasFilename() const { return m_filename; } +const word& fileAttachment::fileInfo::getFilename() const { return *m_filename; } void fileAttachment::fileInfo::setFilename(const string& name) { if (m_filename) { *m_filename = name; } else { m_filename = new word(name); } } void fileAttachment::fileInfo::setFilename(const word& name) { if (m_filename) { *m_filename = name; } else { m_filename = new word(name); } } -bool fileAttachment::fileInfo::hasCreationDate() const { return (m_creationDate != NULL); } -const datetime& fileAttachment::fileInfo::getCreationDate() const { return (*m_creationDate); } +bool fileAttachment::fileInfo::hasCreationDate() const { return m_creationDate; } +const datetime& fileAttachment::fileInfo::getCreationDate() const { return *m_creationDate; } void fileAttachment::fileInfo::setCreationDate(const datetime& date) { if (m_creationDate) { *m_creationDate = date; } else { m_creationDate = new datetime(date); } } -bool fileAttachment::fileInfo::hasModificationDate() const { return (m_modifDate != NULL); } -const datetime& fileAttachment::fileInfo::getModificationDate() const { return (*m_modifDate); } +bool fileAttachment::fileInfo::hasModificationDate() const { return m_modifDate; } +const datetime& fileAttachment::fileInfo::getModificationDate() const { return *m_modifDate; } void fileAttachment::fileInfo::setModificationDate(const datetime& date) { if (m_modifDate) { *m_modifDate = date; } else { m_modifDate = new datetime(date); } } -bool fileAttachment::fileInfo::hasReadDate() const { return (m_readDate != NULL); } -const datetime& fileAttachment::fileInfo::getReadDate() const { return (*m_readDate); } +bool fileAttachment::fileInfo::hasReadDate() const { return m_readDate; } +const datetime& fileAttachment::fileInfo::getReadDate() const { return *m_readDate; } void fileAttachment::fileInfo::setReadDate(const datetime& date) { if (m_readDate) { *m_readDate = date; } else { m_readDate = new datetime(date); } } -bool fileAttachment::fileInfo::hasSize() const { return (m_size != NULL); } -size_t fileAttachment::fileInfo::getSize() const { return (*m_size); } +bool fileAttachment::fileInfo::hasSize() const { return m_size; } +size_t fileAttachment::fileInfo::getSize() const { return *m_size; } void fileAttachment::fileInfo::setSize(const size_t size) { if (m_size) { *m_size = size; } else { m_size = new size_t(size); } } @@ -220,4 +251,3 @@ void fileAttachment::fileInfo::setSize(const size_t size) { if (m_size) { *m_siz #endif // VMIME_HAVE_FILESYSTEM_FEATURES - diff --git a/src/vmime/fileAttachment.hpp b/src/vmime/fileAttachment.hpp index 03e3e283..c77662f2 100644 --- a/src/vmime/fileAttachment.hpp +++ b/src/vmime/fileAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,29 +37,58 @@ #include "vmime/utility/stream.hpp" -namespace vmime -{ +namespace vmime { /** Attachment of type 'file'. */ +class VMIME_EXPORT fileAttachment : public defaultAttachment { -class VMIME_EXPORT fileAttachment : public defaultAttachment -{ public: - fileAttachment(const string& filepath, const mediaType& type); - fileAttachment(const string& filepath, const mediaType& type, const text& desc); - fileAttachment(const string& filepath, const mediaType& type, const text& desc, const encoding& enc); + fileAttachment( + const string& filepath, + const mediaType& type + ); - fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type); - fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc); - fileAttachment(const shared_ptr & cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc); + fileAttachment( + const string& filepath, + const mediaType& type, + const text& desc + ); + + fileAttachment( + const string& filepath, + const mediaType& type, + const text& desc, + const encoding& enc + ); + + fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type + ); + + fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type, + const text& desc + ); + + fileAttachment( + const shared_ptr & cts, + const word& filename, + const mediaType& type, + const text& desc, + const encoding& enc + ); /** Stores information about a file attachment. */ - class VMIME_EXPORT fileInfo - { + class VMIME_EXPORT fileInfo { + public: fileInfo(); diff --git a/src/vmime/fileContentHandler.cpp b/src/vmime/fileContentHandler.cpp index 531151b4..baedf69c 100644 --- a/src/vmime/fileContentHandler.cpp +++ b/src/vmime/fileContentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,57 +30,61 @@ #include "vmime/fileContentHandler.hpp" -namespace vmime -{ +namespace vmime { fileContentHandler::fileContentHandler() - : streamContentHandler() -{ + : streamContentHandler() { + } -fileContentHandler::fileContentHandler - (const shared_ptr & file, const vmime::encoding& enc) -{ +fileContentHandler::fileContentHandler( + const shared_ptr & file, + const vmime::encoding& enc +) { + setData(file, enc); } -fileContentHandler::~fileContentHandler() -{ +fileContentHandler::~fileContentHandler() { + } fileContentHandler::fileContentHandler(const fileContentHandler& cts) - : streamContentHandler() -{ + : streamContentHandler() { + setData(cts.m_file, cts.m_encoding); } -fileContentHandler& fileContentHandler::operator=(const fileContentHandler& cts) -{ +fileContentHandler& fileContentHandler::operator=(const fileContentHandler& cts) { + setData(cts.m_file, cts.m_encoding); return *this; } -shared_ptr fileContentHandler::clone() const -{ +shared_ptr fileContentHandler::clone() const { + return make_shared (*this); } -void fileContentHandler::setData - (const shared_ptr & file, const vmime::encoding& enc) -{ +void fileContentHandler::setData( + const shared_ptr & file, + const vmime::encoding& enc +) { + m_file = file; m_encoding = enc; - streamContentHandler::setData - (file->getFileReader()->getInputStream(), file->getLength(), enc); + streamContentHandler::setData( + file->getFileReader()->getInputStream(), file->getLength(), enc + ); } diff --git a/src/vmime/fileContentHandler.hpp b/src/vmime/fileContentHandler.hpp index 1436a002..80df0695 100644 --- a/src/vmime/fileContentHandler.hpp +++ b/src/vmime/fileContentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,13 @@ #include "vmime/utility/file.hpp" -namespace vmime -{ +namespace vmime { /** A content handler which obtains its data from a file. */ +class VMIME_EXPORT fileContentHandler : public streamContentHandler { -class VMIME_EXPORT fileContentHandler : public streamContentHandler -{ public: /** Creates a new empty content handler. No data can be extracted until @@ -61,9 +59,10 @@ public: * * @return a reference to a new content handler */ - fileContentHandler - (const shared_ptr & file, - const vmime::encoding& enc = NO_ENCODING); + fileContentHandler( + const shared_ptr & file, + const vmime::encoding& enc = NO_ENCODING + ); ~fileContentHandler(); @@ -78,9 +77,10 @@ public: * @param enc set to anything other than NO_ENCODING if the data contained * in the file is already encoded with the specified encoding */ - void setData - (const shared_ptr & file, - const vmime::encoding& enc = NO_ENCODING); + void setData( + const shared_ptr & file, + const vmime::encoding& enc = NO_ENCODING + ); private: diff --git a/src/vmime/generatedMessageAttachment.cpp b/src/vmime/generatedMessageAttachment.cpp index b58b56d8..ad9e678a 100644 --- a/src/vmime/generatedMessageAttachment.cpp +++ b/src/vmime/generatedMessageAttachment.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,62 +26,63 @@ #include "vmime/utility/outputStreamAdapter.hpp" -namespace vmime -{ +namespace vmime { -generatedMessageAttachment::generatedMessageAttachment(const shared_ptr & part) - : m_bpa(make_shared (part)) -{ +generatedMessageAttachment::generatedMessageAttachment( + const shared_ptr & part +) + : m_bpa(make_shared (part)) { + } -const mediaType generatedMessageAttachment::getType() const -{ +const mediaType generatedMessageAttachment::getType() const { + return mediaType(mediaTypes::MESSAGE, mediaTypes::MESSAGE_RFC822); } -const text generatedMessageAttachment::getDescription() const -{ +const text generatedMessageAttachment::getDescription() const { + return m_bpa->getDescription(); } -const word generatedMessageAttachment::getName() const -{ +const word generatedMessageAttachment::getName() const { + return m_bpa->getName(); } -const shared_ptr generatedMessageAttachment::getData() const -{ +const shared_ptr generatedMessageAttachment::getData() const { + return m_bpa->getData(); } -const encoding generatedMessageAttachment::getEncoding() const -{ +const encoding generatedMessageAttachment::getEncoding() const { + return m_bpa->getEncoding(); } -shared_ptr generatedMessageAttachment::getPart() const -{ +shared_ptr generatedMessageAttachment::getPart() const { + return m_bpa->getPart(); } -shared_ptr generatedMessageAttachment::getHeader() const -{ +shared_ptr generatedMessageAttachment::getHeader() const { + return m_bpa->getHeader(); } -shared_ptr generatedMessageAttachment::getMessage() const -{ - if (m_msg == NULL) - { +shared_ptr generatedMessageAttachment::getMessage() const { + + if (!m_msg) { + // Extract data std::ostringstream oss; utility::outputStreamAdapter os(oss); @@ -97,8 +98,8 @@ shared_ptr generatedMessageAttachment::getMessage() const } -void generatedMessageAttachment::generateIn(const shared_ptr & /* parent */) const -{ +void generatedMessageAttachment::generateIn(const shared_ptr & /* parent */) const { + // Not used (see 'parsedMessageAttachment') } diff --git a/src/vmime/generatedMessageAttachment.hpp b/src/vmime/generatedMessageAttachment.hpp index e1e00cc7..b65fcc15 100644 --- a/src/vmime/generatedMessageAttachment.hpp +++ b/src/vmime/generatedMessageAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,14 +32,13 @@ #include "vmime/bodyPartAttachment.hpp" -namespace vmime -{ +namespace vmime { /** A message attachment that can be extracted from a message. */ -class VMIME_EXPORT generatedMessageAttachment : public messageAttachment -{ +class VMIME_EXPORT generatedMessageAttachment : public messageAttachment { + public: generatedMessageAttachment(const shared_ptr & part); @@ -76,4 +75,3 @@ private: #endif // VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED - diff --git a/src/vmime/generationContext.cpp b/src/vmime/generationContext.cpp index 4b637432..24757c70 100644 --- a/src/vmime/generationContext.cpp +++ b/src/vmime/generationContext.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,8 +24,7 @@ #include "vmime/generationContext.hpp" -namespace vmime -{ +namespace vmime { generationContext::generationContext() @@ -34,8 +33,8 @@ generationContext::generationContext() "does not understand MIME message format."), m_epilogText(""), m_wrapMessageId(true), - m_paramValueMode(PARAMETER_VALUE_RFC2231_ONLY) -{ + m_paramValueMode(PARAMETER_VALUE_RFC2231_ONLY) { + } @@ -45,86 +44,89 @@ generationContext::generationContext(const generationContext& ctx) m_prologText(ctx.m_prologText), m_epilogText(ctx.m_epilogText), m_wrapMessageId(ctx.m_wrapMessageId), - m_paramValueMode(ctx.m_paramValueMode) -{ + m_paramValueMode(ctx.m_paramValueMode) { + } -generationContext& generationContext::getDefaultContext() -{ +generationContext& generationContext::getDefaultContext() { + static generationContext ctx; return ctx; } -size_t generationContext::getMaxLineLength() const -{ +size_t generationContext::getMaxLineLength() const { + return m_maxLineLength; } -void generationContext::setMaxLineLength(const size_t maxLineLength) -{ +void generationContext::setMaxLineLength(const size_t maxLineLength) { + m_maxLineLength = maxLineLength; } -const string generationContext::getPrologText() const -{ +const string generationContext::getPrologText() const { + return m_prologText; } -void generationContext::setPrologText(const string& prologText) -{ +void generationContext::setPrologText(const string& prologText) { + m_prologText = prologText; } -const string generationContext::getEpilogText() const -{ +const string generationContext::getEpilogText() const { + return m_epilogText; } -void generationContext::setEpilogText(const string& epilogText) -{ +void generationContext::setEpilogText(const string& epilogText) { + m_epilogText = epilogText; } -bool generationContext::getWrapMessageId() const -{ + +bool generationContext::getWrapMessageId() const { + return m_wrapMessageId; } -void generationContext::setWrapMessageId(const bool& wrapMessageId) -{ + +void generationContext::setWrapMessageId(const bool& wrapMessageId) { + m_wrapMessageId = wrapMessageId; } -void generationContext::setEncodedParameterValueMode(const EncodedParameterValueModes mode) -{ + +void generationContext::setEncodedParameterValueMode(const EncodedParameterValueModes mode) { + m_paramValueMode = mode; } generationContext::EncodedParameterValueModes - generationContext::getEncodedParameterValueMode() const -{ + generationContext::getEncodedParameterValueMode() const { + return m_paramValueMode; } -generationContext& generationContext::operator=(const generationContext& ctx) -{ +generationContext& generationContext::operator=(const generationContext& ctx) { + copyFrom(ctx); return *this; } -void generationContext::copyFrom(const generationContext& ctx) -{ +void generationContext::copyFrom(const generationContext& ctx) { + context::copyFrom(ctx); m_maxLineLength = ctx.m_maxLineLength; diff --git a/src/vmime/generationContext.hpp b/src/vmime/generationContext.hpp index 1cb4ce67..5e36513c 100644 --- a/src/vmime/generationContext.hpp +++ b/src/vmime/generationContext.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/context.hpp" -namespace vmime -{ +namespace vmime { /** Holds configuration parameters used for generating messages. */ +class VMIME_EXPORT generationContext : public context { -class VMIME_EXPORT generationContext : public context -{ public: generationContext(); @@ -103,8 +101,8 @@ public: /** Modes available for generating values in parameterized header fields. */ - enum EncodedParameterValueModes - { + enum EncodedParameterValueModes { + PARAMETER_VALUE_NO_ENCODING, /**< Only generate 7-bit (ASCII-only) values, even if the value contains non-ASCII chars or if folding is needed. */ diff --git a/src/vmime/header.cpp b/src/vmime/header.cpp index cd2a6f7e..c7d7ca08 100644 --- a/src/vmime/header.cpp +++ b/src/vmime/header.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,17 +28,16 @@ #include -namespace vmime -{ +namespace vmime { -header::header() -{ +header::header() { + } -header::~header() -{ +header::~header() { + removeAllFields(); } @@ -62,70 +61,79 @@ field-body-contents = specials tokens, or else consisting of texts> */ -void header::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void header::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + size_t pos = position; removeAllFields(); - while (pos < end) - { + while (pos < end) { + shared_ptr field = headerField::parseNext(ctx, buffer, pos, end, &pos); - if (field == NULL) break; + if (!field) break; m_fields.push_back(field); } setParsedBounds(position, pos); - if (newPosition) + if (newPosition) { *newPosition = pos; + } } -void header::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t /* curLinePos */, size_t* newLinePos) const -{ +void header::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t /* curLinePos */, + size_t* newLinePos +) const { + // Generate the fields for (std::vector >::const_iterator it = m_fields.begin() ; - it != m_fields.end() ; ++it) - { + it != m_fields.end() ; ++it) { + (*it)->generate(ctx, os); os << CRLF; } - if (newLinePos) + if (newLinePos) { *newLinePos = 0; + } } -size_t header::getGeneratedSize(const generationContext& ctx) -{ +size_t header::getGeneratedSize(const generationContext& ctx) { + return component::getGeneratedSize(ctx) + 2 * m_fields.size() /* CRLF */; } -shared_ptr header::clone() const -{ +shared_ptr header::clone() const { + shared_ptr
hdr = make_shared
(); hdr->m_fields.reserve(m_fields.size()); for (std::vector >::const_iterator it = m_fields.begin() ; - it != m_fields.end() ; ++it) - { + it != m_fields.end() ; ++it) { + hdr->m_fields.push_back(vmime::clone(*it)); } - return (hdr); + return hdr; } -void header::copyFrom(const component& other) -{ +void header::copyFrom(const component& other) { + const header& h = dynamic_cast (other); std::vector > fields; @@ -133,8 +141,8 @@ void header::copyFrom(const component& other) fields.reserve(h.m_fields.size()); for (std::vector >::const_iterator it = h.m_fields.begin() ; - it != h.m_fields.end() ; ++it) - { + it != h.m_fields.end() ; ++it) { + fields.push_back(vmime::clone(*it)); } @@ -145,217 +153,238 @@ void header::copyFrom(const component& other) } -header& header::operator=(const header& other) -{ +header& header::operator=(const header& other) { + copyFrom(other); - return (*this); + return *this; } -bool header::hasField(const string& fieldName) const -{ +bool header::hasField(const string& fieldName) const { + std::vector >::const_iterator pos = - std::find_if(m_fields.begin(), m_fields.end(), - fieldHasName(utility::stringUtils::toLower(fieldName))); + std::find_if( + m_fields.begin(), m_fields.end(), + fieldHasName(utility::stringUtils::toLower(fieldName)) + ); - return (pos != m_fields.end()); + return pos != m_fields.end(); } -shared_ptr header::findField(const string& fieldName) const -{ +shared_ptr header::findField(const string& fieldName) const { + // Find the first field that matches the specified name std::vector >::const_iterator pos = - std::find_if(m_fields.begin(), m_fields.end(), - fieldHasName(utility::stringUtils::toLower(fieldName))); + std::find_if( + m_fields.begin(), m_fields.end(), + fieldHasName(utility::stringUtils::toLower(fieldName)) + ); // No field with this name can be found - if (pos == m_fields.end()) + if (pos == m_fields.end()) { return null; + } // Else, return a reference to the existing field - return (*pos); + return *pos; } -std::vector > header::findAllFields(const string& fieldName) -{ +std::vector > header::findAllFields(const string& fieldName) { + std::vector > result; std::back_insert_iterator > > back(result); - std::remove_copy_if(m_fields.begin(), m_fields.end(), back, - fieldHasNotName(utility::stringUtils::toLower(fieldName))); + std::remove_copy_if( + m_fields.begin(), m_fields.end(), back, + fieldHasNotName(utility::stringUtils::toLower(fieldName)) + ); return result; } -shared_ptr header::getField(const string& fieldName) -{ +shared_ptr header::getField(const string& fieldName) { + const string name = utility::stringUtils::toLower(fieldName); // Find the first field that matches the specified name std::vector >::const_iterator pos = m_fields.begin(); const std::vector >::const_iterator end = m_fields.end(); - while (pos != end && utility::stringUtils::toLower((*pos)->getName()) != name) + while (pos != end && utility::stringUtils::toLower((*pos)->getName()) != name) { ++pos; + } // If no field with this name can be found, create a new one - if (pos == end) - { + if (pos == end) { + shared_ptr field = headerFieldFactory::getInstance()->create(fieldName); appendField(field); // Return a reference to the new field return (field); - } + // Else, return a reference to the existing field - else - { - return (*pos); + } else { + + return *pos; } } -void header::appendField(const shared_ptr & field) -{ +void header::appendField(const shared_ptr & field) { + m_fields.push_back(field); } -void header::insertFieldBefore(const shared_ptr & beforeField, const shared_ptr & field) -{ - const std::vector >::iterator it = std::find - (m_fields.begin(), m_fields.end(), beforeField); +void header::insertFieldBefore( + const shared_ptr & beforeField, + const shared_ptr & field +) { - if (it == m_fields.end()) + const std::vector >::iterator it = + std::find(m_fields.begin(), m_fields.end(), beforeField); + + if (it == m_fields.end()) { throw exceptions::no_such_field(); + } m_fields.insert(it, field); } -void header::insertFieldBefore(const size_t pos, const shared_ptr & field) -{ +void header::insertFieldBefore(const size_t pos, const shared_ptr & field) { + m_fields.insert(m_fields.begin() + pos, field); } -void header::insertFieldAfter(const shared_ptr & afterField, const shared_ptr & field) -{ - const std::vector >::iterator it = std::find - (m_fields.begin(), m_fields.end(), afterField); +void header::insertFieldAfter( + const shared_ptr & afterField, + const shared_ptr & field +) { - if (it == m_fields.end()) + const std::vector >::iterator it = + std::find(m_fields.begin(), m_fields.end(), afterField); + + if (it == m_fields.end()) { throw exceptions::no_such_field(); + } m_fields.insert(it + 1, field); } -void header::insertFieldAfter(const size_t pos, const shared_ptr & field) -{ +void header::insertFieldAfter(const size_t pos, const shared_ptr & field) { + m_fields.insert(m_fields.begin() + pos + 1, field); } -void header::removeField(const shared_ptr & field) -{ - const std::vector >::iterator it = std::find - (m_fields.begin(), m_fields.end(), field); +void header::removeField(const shared_ptr & field) { - if (it == m_fields.end()) + const std::vector >::iterator it = + std::find(m_fields.begin(), m_fields.end(), field); + + if (it == m_fields.end()) { throw exceptions::no_such_field(); + } m_fields.erase(it); } -void header::removeField(const size_t pos) -{ +void header::removeField(const size_t pos) { + const std::vector >::iterator it = m_fields.begin() + pos; m_fields.erase(it); } -void header::replaceField(const shared_ptr & field, const shared_ptr & newField) -{ +void header::replaceField( + const shared_ptr & field, + const shared_ptr & newField +) { + insertFieldBefore(field, newField); removeField(field); } -void header::removeAllFields() -{ +void header::removeAllFields() { + m_fields.clear(); } -void header::removeAllFields(const string& fieldName) -{ +void header::removeAllFields(const string& fieldName) { + std::vector > fields = findAllFields(fieldName); - for (unsigned int i = 0 ; i < fields.size() ; ++i) + for (unsigned int i = 0 ; i < fields.size() ; ++i) { removeField(fields[i]); + } } -size_t header::getFieldCount() const -{ - return (m_fields.size()); +size_t header::getFieldCount() const { + + return m_fields.size(); } -bool header::isEmpty() const -{ - return (m_fields.empty()); +bool header::isEmpty() const { + + return m_fields.empty(); } -const shared_ptr header::getFieldAt(const size_t pos) -{ - return (m_fields[pos]); +const shared_ptr header::getFieldAt(const size_t pos) { + + return m_fields[pos]; } -const shared_ptr header::getFieldAt(const size_t pos) const -{ - return (m_fields[pos]); +const shared_ptr header::getFieldAt(const size_t pos) const { + + return m_fields[pos]; } -const std::vector > header::getFieldList() const -{ +const std::vector > header::getFieldList() const { + std::vector > list; list.reserve(m_fields.size()); for (std::vector >::const_iterator it = m_fields.begin() ; - it != m_fields.end() ; ++it) - { + it != m_fields.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > header::getFieldList() -{ - return (m_fields); +const std::vector > header::getFieldList() { + + return m_fields; } -const std::vector > header::getChildComponents() -{ +const std::vector > header::getChildComponents() { + std::vector > list; copy_vector(m_fields, list); - return (list); + return list; } @@ -364,23 +393,23 @@ const std::vector > header::getChildComponents() header::fieldHasName::fieldHasName(const string& name) - : m_name(name) -{ + : m_name(name) { + } -bool header::fieldHasName::operator() (const shared_ptr & field) -{ +bool header::fieldHasName::operator() (const shared_ptr & field) { + return utility::stringUtils::toLower(field->getName()) == m_name; } header::fieldHasNotName::fieldHasNotName(const string& name) - : m_name(name) -{ + : m_name(name) { + } -bool header::fieldHasNotName::operator() (const shared_ptr & field) -{ +bool header::fieldHasNotName::operator() (const shared_ptr & field) { + return utility::stringUtils::toLower(field->getName()) != m_name; } diff --git a/src/vmime/header.hpp b/src/vmime/header.hpp index f2fd0666..7b4a1616 100644 --- a/src/vmime/header.hpp +++ b/src/vmime/header.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,8 +33,7 @@ #include "vmime/headerFieldFactory.hpp" -namespace vmime -{ +namespace vmime { class bodyPart; @@ -42,9 +41,8 @@ class bodyPart; /** Header section of a MIME part. */ +class VMIME_EXPORT header : public component { -class VMIME_EXPORT header : public component -{ friend class bodyPart; friend class body; friend class message; @@ -120,8 +118,8 @@ public: * with this name was found */ template - shared_ptr findField(const string& fieldName) const - { + shared_ptr findField(const string& fieldName) const { + return dynamicCast (findField(fieldName)); } @@ -137,14 +135,15 @@ public: * specified type */ template - shared_ptr findFieldValue(const string& fieldName) const - { + shared_ptr findFieldValue(const string& fieldName) const { + shared_ptr field = findField(fieldName); - if (field) + if (field) { return dynamicCast (field->getValue()); - else + } else { return null; + } } /** Find all fields that match the specified name. @@ -176,8 +175,8 @@ public: * if no field is found */ template - shared_ptr getField(const string& fieldName) - { + shared_ptr getField(const string& fieldName) { + return dynamicCast (getField(fieldName)); } @@ -193,7 +192,10 @@ public: * @param field field to insert * @throw exceptions::no_such_field if the field is not in the list */ - void insertFieldBefore(const shared_ptr & beforeField, const shared_ptr & field); + void insertFieldBefore( + const shared_ptr & beforeField, + const shared_ptr & field + ); /** Insert a new field before the specified position. * @@ -201,7 +203,10 @@ public: * the beginning of the list) * @param field field to insert */ - void insertFieldBefore(const size_t pos, const shared_ptr & field); + void insertFieldBefore( + const size_t pos, + const shared_ptr & field + ); /** Insert a new field after the specified field. * @@ -209,14 +214,20 @@ public: * @param field field to insert * @throw exceptions::no_such_field if the field is not in the list */ - void insertFieldAfter(const shared_ptr & afterField, const shared_ptr & field); + void insertFieldAfter( + const shared_ptr & afterField, + const shared_ptr & field + ); /** Insert a new field after the specified position. * * @param pos position of the field before the new field * @param field field to insert */ - void insertFieldAfter(const size_t pos, const shared_ptr & field); + void insertFieldAfter( + const size_t pos, + const shared_ptr & field + ); /** Remove the specified field from the list. * @@ -237,7 +248,10 @@ public: * @param newField field to replace with * @throw exceptions::no_such_field if the field is not in the list */ - void replaceField(const shared_ptr & field, const shared_ptr & newField); + void replaceField( + const shared_ptr & field, + const shared_ptr & newField + ); /** Remove all fields from the list. */ @@ -298,8 +312,8 @@ private: std::vector > m_fields; - class fieldHasName - { + class fieldHasName { + public: fieldHasName(const string& name); @@ -310,8 +324,8 @@ private: string m_name; }; - class fieldHasNotName - { + class fieldHasNotName { + public: fieldHasNotName(const string& name); @@ -325,18 +339,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/headerField.cpp b/src/vmime/headerField.cpp index 05f5b046..bff365dc 100644 --- a/src/vmime/headerField.cpp +++ b/src/vmime/headerField.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,130 +29,147 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { headerField::headerField() - : m_name("X-Undefined") -{ + : m_name("X-Undefined") { + } headerField::headerField(const string& fieldName) - : m_name(fieldName) -{ + : m_name(fieldName) { + } -headerField::~headerField() -{ +headerField::~headerField() { + } -shared_ptr headerField::clone() const -{ +shared_ptr headerField::clone() const { + shared_ptr field = headerFieldFactory::getInstance()->create(m_name); field->copyFrom(*this); - return (field); + return field; } -void headerField::copyFrom(const component& other) -{ +void headerField::copyFrom(const component& other) { + const headerField& hf = dynamic_cast (other); m_value->copyFrom(*hf.m_value); } -headerField& headerField::operator=(const headerField& other) -{ +headerField& headerField::operator=(const headerField& other) { + copyFrom(other); - return (*this); + return *this; } -shared_ptr headerField::parseNext - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +shared_ptr headerField::parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + size_t pos = position; - while (pos < end) - { + while (pos < end) { + char_t c = buffer[pos]; // Check for end of headers (empty line): although RFC-822 recommends // to use CRLF for header/body separator (see 4.1 SYNTAX), here, we // also check for LF for compatibility with broken implementations... - if (c == '\n') - { - if (newPosition) + if (c == '\n') { + + if (newPosition) { *newPosition = pos + 1; // LF: illegal + } return null; - } - else if (c == '\r' && pos + 1 < end && buffer[pos + 1] == '\n') - { - if (newPosition) + + } else if (c == '\r' && pos + 1 < end && buffer[pos + 1] == '\n') { + + if (newPosition) { *newPosition = pos + 2; // CR+LF + } return null; } // This line may be a field description - if (!parserHelpers::isSpace(c)) - { + if (!parserHelpers::isSpace(c)) { + const size_t nameStart = pos; // remember the start position of the line - while (pos < end && (buffer[pos] != ':' && !parserHelpers::isSpace(buffer[pos]))) + while (pos < end && (buffer[pos] != ':' && !parserHelpers::isSpace(buffer[pos]))) { ++pos; + } const size_t nameEnd = pos; - while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) + while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) { ++pos; + } + + if (buffer[pos] != ':') { - if (buffer[pos] != ':') - { switch (ctx.getHeaderParseErrorRecoveryMethod()) { + case vmime::headerParseRecoveryMethod::SKIP_LINE: // Humm...does not seem to be a valid header line. // Skip this error and advance to the next line pos = nameStart; - while (pos < end && buffer[pos] != '\n') + while (pos < end && buffer[pos] != '\n') { ++pos; + } - if (pos < end && buffer[pos] == '\n') + if (pos < end && buffer[pos] == '\n') { ++pos; + } + break; // case vmime::headerParseRecoveryMethod::APPEND_TO_PREVIOUS_LINE: +// // // TODO Implement this... // break; case vmime::headerParseRecoveryMethod::ASSUME_END_OF_HEADERS: + return null; break; } - } - else - { + + } else { + // Extract the field name - const string name(buffer.begin() + nameStart, - buffer.begin() + nameEnd); + const string name( + buffer.begin() + nameStart, + buffer.begin() + nameEnd + ); // Skip ':' character - while (pos < end && buffer[pos] == ':') + while (pos < end && buffer[pos] == ':') { ++pos; + } // Skip spaces between ':' and the field contents - while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) + while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) { ++pos; + } const size_t contentsStart = pos; size_t contentsEnd = 0; @@ -160,19 +177,20 @@ shared_ptr headerField::parseNext bool firstLine = true; // Parse field value, taking care of line folding (value on multiple lines) - for (size_t eol = 0 ; parserHelpers::findEOL(buffer, pos, end, &eol) ; pos = eol) - { + for (size_t eol = 0 ; parserHelpers::findEOL(buffer, pos, end, &eol) ; pos = eol) { + // If the line does not start with a folding indicator (SPACE or TAB), // and this is not the first line, then stop parsing lines - if (!firstLine && !(buffer[pos] == ' ' || buffer[pos] == '\t')) + if (!firstLine && !(buffer[pos] == ' ' || buffer[pos] == '\t')) { break; + } contentsEnd = eol; firstLine = false; } - if (pos == end && contentsEnd == 0) - { + if (pos == end && contentsEnd == 0) { + // End of data, and no CRLF was found at the end contentsEnd = end; } @@ -180,8 +198,8 @@ shared_ptr headerField::parseNext // Strip spaces from end of header lines while (contentsEnd > contentsStart && (buffer[contentsEnd - 1] == ' ' || buffer[contentsEnd - 1] == '\t' || - buffer[contentsEnd - 1] == '\r' || buffer[contentsEnd - 1] == '\n')) - { + buffer[contentsEnd - 1] == '\r' || buffer[contentsEnd - 1] == '\n')) { + contentsEnd--; } @@ -191,145 +209,164 @@ shared_ptr headerField::parseNext field->parse(ctx, buffer, contentsStart, contentsEnd, NULL); field->setParsedBounds(nameStart, pos); - if (newPosition) + if (newPosition) { *newPosition = pos; + } - return (field); + return field; } - } - else - { + + } else { + // If the line contains only space characters, we assume it is // the end of the headers. - while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) + while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) { ++pos; + } - if (pos < end && buffer[pos] == '\n') - { - if (newPosition) + if (pos < end && buffer[pos] == '\n') { + + if (newPosition) { *newPosition = pos + 1; // LF: illegal + } return null; - } - else if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] == '\n') - { - if (newPosition) + + } else if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] == '\n') { + + if (newPosition) { *newPosition = pos + 2; // CR+LF + } return null; } // Skip this error and advance to the next line - while (pos < end && buffer[pos] != '\n') + while (pos < end && buffer[pos] != '\n') { ++pos; + } - if (buffer[pos] == '\n') + if (buffer[pos] == '\n') { ++pos; + } } } - if (newPosition) + if (newPosition) { *newPosition = pos; + } return null; } -void headerField::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void headerField::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_value->parse(ctx, buffer, position, end, newPosition); } -void headerField::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void headerField::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + os << m_name + ": "; m_value->generate(ctx, os, curLinePos + m_name.length() + 2, newLinePos); } -size_t headerField::getGeneratedSize(const generationContext& ctx) -{ +size_t headerField::getGeneratedSize(const generationContext& ctx) { + return m_name.length() + 2 /* ": " */ + m_value->getGeneratedSize(ctx); } -const string headerField::getName() const -{ +const string headerField::getName() const { + return m_name; } -void headerField::setName(const string& name) -{ +void headerField::setName(const string& name) { + m_name = name; } -bool headerField::isCustom() const -{ - return (m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-'); +bool headerField::isCustom() const { + + return m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-'; } -const std::vector > headerField::getChildComponents() -{ +const std::vector > headerField::getChildComponents() { + std::vector > list; - if (m_value) + if (m_value) { list.push_back(m_value); + } - return (list); + return list; } -shared_ptr headerField::getValue() const -{ +shared_ptr headerField::getValue() const { + return m_value; } -shared_ptr headerField::getValue() -{ +shared_ptr headerField::getValue() { + return m_value; } -void headerField::setValue(const shared_ptr & value) -{ - if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) +void headerField::setValue(const shared_ptr & value) { + + if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) { throw exceptions::bad_field_value_type(getName()); + } - if (value != NULL) + if (value != NULL) { m_value = value; + } } -void headerField::setValueConst(const shared_ptr & value) -{ - if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) +void headerField::setValueConst(const shared_ptr & value) { + + if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) { throw exceptions::bad_field_value_type(getName()); + } m_value = vmime::clone(value); } -void headerField::setValue(const headerFieldValue& value) -{ - if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, value)) +void headerField::setValue(const headerFieldValue& value) { + + if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, value)) { throw exceptions::bad_field_value_type(getName()); + } m_value = vmime::clone(value); } -void headerField::setValue(const string& value) -{ +void headerField::setValue(const string& value) { + parse(value); } diff --git a/src/vmime/headerField.hpp b/src/vmime/headerField.hpp index 9c49235c..66e99460 100644 --- a/src/vmime/headerField.hpp +++ b/src/vmime/headerField.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,15 +30,13 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** Base class for header fields. */ +class VMIME_EXPORT headerField : public component { -class VMIME_EXPORT headerField : public component -{ friend class headerFieldFactory; friend class header; @@ -90,8 +88,8 @@ public: * @return value object */ template - shared_ptr getValue() const - { + shared_ptr getValue() const { + return dynamicCast (m_value); } @@ -107,8 +105,8 @@ public: * @return value object */ template - shared_ptr getValue() - { + shared_ptr getValue() { + return dynamicCast (m_value); } @@ -154,29 +152,32 @@ public: * @return parsed header field, or NULL if no more header field can be parsed * in the input buffer */ - static shared_ptr parseNext - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + static shared_ptr parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); size_t getGeneratedSize(const generationContext& ctx); protected: - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; string m_name; diff --git a/src/vmime/headerFieldFactory.cpp b/src/vmime/headerFieldFactory.cpp index 5c60543e..db281fae 100644 --- a/src/vmime/headerFieldFactory.cpp +++ b/src/vmime/headerFieldFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,12 +38,11 @@ #include "vmime/mailboxField.hpp" -namespace vmime -{ +namespace vmime { -headerFieldFactory::headerFieldFactory() -{ +headerFieldFactory::headerFieldFactory() { + // Register parameterized fields registerField (vmime::fields::CONTENT_TYPE); registerField (vmime::fields::CONTENT_TRANSFER_ENCODING); @@ -85,67 +84,75 @@ headerFieldFactory::headerFieldFactory() } -headerFieldFactory::~headerFieldFactory() -{ +headerFieldFactory::~headerFieldFactory() { + } -shared_ptr headerFieldFactory::getInstance() -{ +shared_ptr headerFieldFactory::getInstance() { + static headerFieldFactory instance; return shared_ptr (&instance, noop_shared_ptr_deleter ()); } -shared_ptr headerFieldFactory::create - (const string& name, const string& body) -{ +shared_ptr headerFieldFactory::create( + const string& name, + const string& body +) { + NameMap::const_iterator pos = m_nameMap.find(utility::stringUtils::toLower(name)); shared_ptr field; - if (pos != m_nameMap.end()) + if (pos != m_nameMap.end()) { field = ((*pos).second)(); - else + } else { field = registerer ::creator(); + } field->setName(name); field->setValue(createValue(name)); - if (body != NULL_STRING) + if (body != NULL_STRING) { field->parse(body); + } return field; } -shared_ptr headerFieldFactory::createValue(const string& fieldName) -{ - ValueMap::const_iterator pos = m_valueMap.find - (utility::stringUtils::toLower(fieldName)); +shared_ptr headerFieldFactory::createValue(const string& fieldName) { + + ValueMap::const_iterator pos = m_valueMap.find( + utility::stringUtils::toLower(fieldName) + ); shared_ptr value; - if (pos != m_valueMap.end()) + if (pos != m_valueMap.end()) { value = ((*pos).second.allocFunc)(); - else + } else { value = registerer ::creator(); + } return value; } -bool headerFieldFactory::isValueTypeValid - (const headerField& field, const headerFieldValue& value) const -{ +bool headerFieldFactory::isValueTypeValid( + const headerField& field, + const headerFieldValue& value +) const { + ValueMap::const_iterator pos = m_valueMap.find (utility::stringUtils::toLower(field.getName())); - if (pos != m_valueMap.end()) + if (pos != m_valueMap.end()) { return ((*pos).second.checkTypeFunc)(value); + } return true; // No info on this field } } // vmime - diff --git a/src/vmime/headerFieldFactory.hpp b/src/vmime/headerFieldFactory.hpp index 960f27b7..b3e34159 100644 --- a/src/vmime/headerFieldFactory.hpp +++ b/src/vmime/headerFieldFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { /** Creates header field and header field value objects. */ +class VMIME_EXPORT headerFieldFactory { -class VMIME_EXPORT headerFieldFactory -{ protected: headerFieldFactory(); @@ -49,8 +47,8 @@ protected: NameMap m_nameMap; - struct ValueInfo - { + struct ValueInfo { + typedef shared_ptr (*ValueAllocFunc)(void); typedef bool (*ValueTypeCheckFunc)(const object&); @@ -67,24 +65,26 @@ public: static shared_ptr getInstance(); #ifndef VMIME_BUILDING_DOC + // TYPE must inherit from BASE_TYPE template - class registerer - { + class registerer { + public: - static bool checkType(const object& obj) - { + static bool checkType(const object& obj) { + const TYPE* typedObj = dynamic_cast (&obj); return typedObj != NULL; } - static shared_ptr creator() - { + static shared_ptr creator() { + // Allocate a new object return shared_ptr (new TYPE()); } }; + #endif // VMIME_BUILDING_DOC @@ -94,11 +94,14 @@ public: * @param name field name (eg. "X-MyField") */ template - void registerField(const string& name) - { - m_nameMap.insert(NameMap::value_type - (utility::stringUtils::toLower(name), - ®isterer ::creator)); + void registerField(const string& name) { + + m_nameMap.insert( + NameMap::value_type( + utility::stringUtils::toLower(name), + ®isterer ::creator + ) + ); } /** Register a field value type. @@ -107,14 +110,18 @@ public: * @param name field name */ template - void registerFieldValue(const string& name) - { + void registerFieldValue(const string& name) { + ValueInfo vi; vi.allocFunc = ®isterer ::creator; vi.checkTypeFunc = ®isterer ::checkType; - m_valueMap.insert(ValueMap::value_type - (utility::stringUtils::toLower(name), vi)); + m_valueMap.insert( + ValueMap::value_type( + utility::stringUtils::toLower(name), + vi + ) + ); } /** Create a new field object for the specified field name. diff --git a/src/vmime/headerFieldValue.cpp b/src/vmime/headerFieldValue.cpp index a93e0061..073edbe5 100644 --- a/src/vmime/headerFieldValue.cpp +++ b/src/vmime/headerFieldValue.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,12 +26,11 @@ #include "vmime/utility/outputStreamAdapter.hpp" -namespace vmime -{ +namespace vmime { -size_t headerFieldValue::getGeneratedSize(const generationContext& ctx) -{ +size_t headerFieldValue::getGeneratedSize(const generationContext& ctx) { + std::ostringstream oss; utility::outputStreamAdapter osa(oss); diff --git a/src/vmime/headerFieldValue.hpp b/src/vmime/headerFieldValue.hpp index a3681953..20d17680 100644 --- a/src/vmime/headerFieldValue.hpp +++ b/src/vmime/headerFieldValue.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,16 +29,14 @@ #include "vmime/component.hpp" -namespace vmime -{ +namespace vmime { /** Base class for all classes that can be used as a value * for a header field. */ +class VMIME_EXPORT headerFieldValue : public component { -class VMIME_EXPORT headerFieldValue : public component -{ public: size_t getGeneratedSize(const generationContext& ctx); @@ -49,4 +47,3 @@ public: #endif // VMIME_HEADERFIELDVALUE_HPP_INCLUDED - diff --git a/src/vmime/htmlTextPart.cpp b/src/vmime/htmlTextPart.cpp index bda33cc0..a30023c6 100644 --- a/src/vmime/htmlTextPart.cpp +++ b/src/vmime/htmlTextPart.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,47 +34,52 @@ #include "vmime/utility/outputStreamAdapter.hpp" -namespace vmime -{ +namespace vmime { htmlTextPart::htmlTextPart() : m_plainText(make_shared ()), - m_text(make_shared ()) -{ + m_text(make_shared ()) { + } -htmlTextPart::~htmlTextPart() -{ +htmlTextPart::~htmlTextPart() { + } -const mediaType htmlTextPart::getType() const -{ +const mediaType htmlTextPart::getType() const { + return mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML); } -size_t htmlTextPart::getPartCount() const -{ - return (m_plainText->isEmpty() ? 1 : 2); +size_t htmlTextPart::getPartCount() const { + + return m_plainText->isEmpty() ? 1 : 2; } -void htmlTextPart::generateIn(const shared_ptr & /* message */, const shared_ptr & parent) const -{ +void htmlTextPart::generateIn( + const shared_ptr & /* message */, + const shared_ptr & parent +) const { + // Plain text - if (!m_plainText->isEmpty()) - { + if (!m_plainText->isEmpty()) { + // -- Create a new part shared_ptr part = make_shared (); parent->getBody()->appendPart(part); // -- Set contents - part->getBody()->setContents(m_plainText, - mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), m_charset, - encoding::decide(m_plainText, m_charset, encoding::USAGE_TEXT)); + part->getBody()->setContents( + m_plainText, + mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), + m_charset, + encoding::decide(m_plainText, m_charset, encoding::USAGE_TEXT) + ); } // HTML text @@ -82,27 +87,31 @@ void htmlTextPart::generateIn(const shared_ptr & /* message */, const shared_ptr htmlPart = make_shared (); // -- Set contents - htmlPart->getBody()->setContents(m_text, - mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML), m_charset, - encoding::decide(m_text, m_charset, encoding::USAGE_TEXT)); + htmlPart->getBody()->setContents( + m_text, + mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML), + m_charset, + encoding::decide(m_text, m_charset, encoding::USAGE_TEXT) + ); // Handle the case we have embedded objects - if (!m_objects.empty()) - { + if (!m_objects.empty()) { + // Create a "multipart/related" body part shared_ptr relPart = make_shared (); parent->getBody()->appendPart(relPart); - relPart->getHeader()->ContentType()-> - setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED)); + relPart->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED) + ); // Add the HTML part into this part relPart->getBody()->appendPart(htmlPart); // Also add objects into this part for (std::vector >::const_iterator it = m_objects.begin() ; - it != m_objects.end() ; ++it) - { + it != m_objects.end() ; ++it) { + shared_ptr objPart = make_shared (); relPart->getBody()->appendPart(objPart); @@ -112,8 +121,8 @@ void htmlTextPart::generateIn(const shared_ptr & /* message */, const (id[0] == 'c' || id[0] == 'C') && (id[1] == 'i' || id[1] == 'I') && (id[2] == 'd' || id[2] == 'D') && - id[3] == ':') - { + id[3] == ':') { + id = id.substr(4); } @@ -125,38 +134,46 @@ void htmlTextPart::generateIn(const shared_ptr & /* message */, const objPart->getBody()->setContents((*it)->getData()->clone()); } - } - else - { + + } else { + // Add the HTML part into the parent part parent->getBody()->appendPart(htmlPart); } } -void htmlTextPart::findEmbeddedParts(const bodyPart& part, - std::vector >& cidParts, std::vector >& locParts) -{ - for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) - { +void htmlTextPart::findEmbeddedParts( + const bodyPart& part, + std::vector >& cidParts, + std::vector >& locParts +) { + + for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) { + shared_ptr p = part.getBody()->getPartAt(i); // For a part to be an embedded object, it must have either a // Content-Id field or a Content-Location field. - if (p->getHeader()->hasField(fields::CONTENT_ID)) + if (p->getHeader()->hasField(fields::CONTENT_ID)) { cidParts.push_back(p); + } - if (p->getHeader()->hasField(fields::CONTENT_LOCATION)) + if (p->getHeader()->hasField(fields::CONTENT_LOCATION)) { locParts.push_back(p); + } findEmbeddedParts(*p, cidParts, locParts); } } -void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id, - const embeddedObject::ReferenceType refType) -{ +void htmlTextPart::addEmbeddedObject( + const bodyPart& part, + const string& id, + const embeddedObject::ReferenceType refType +) { + // The object may already exists. This can happen if an object is // identified by both a Content-Id and a Content-Location. In this // case, there will be two embedded objects with two different IDs @@ -167,23 +184,33 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id, shared_ptr ctf = part.getHeader()->findField(fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + type = *ctf->getValue (); - } - else - { + + } else { + // No "Content-type" field: assume "application/octet-stream". } - m_objects.push_back(make_shared - (vmime::clone(part.getBody()->getContents()), - part.getBody()->getEncoding(), id, type, refType)); + m_objects.push_back( + make_shared ( + vmime::clone(part.getBody()->getContents()), + part.getBody()->getEncoding(), + id, + type, + refType + ) + ); } -void htmlTextPart::parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart) -{ +void htmlTextPart::parse( + const shared_ptr & message, + const shared_ptr & parent, + const shared_ptr & textPart +) { + // Search for possible embedded objects in the _whole_ message. std::vector > cidParts; std::vector > locParts; @@ -204,39 +231,42 @@ void htmlTextPart::parse(const shared_ptr & message, const share shared_ptr ctf = textPart->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf && ctf->hasCharset()) + if (ctf && ctf->hasCharset()) { m_charset = ctf->getCharset(); - else + } else { m_charset = charset(); + } // Extract embedded objects. The algorithm is quite simple: for each previously // found inline part, we check if its CID/Location is contained in the HTML text. - for (std::vector >::const_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p) - { + for (std::vector >::const_iterator p = cidParts.begin() ; + p != cidParts.end() ; ++p) { + const shared_ptr midField = (*p)->getHeader()->findField(fields::CONTENT_ID); const messageId mid = *midField->getValue (); if (data.find("CID:" + mid.getId()) != string::npos || - data.find("cid:" + mid.getId()) != string::npos) - { + data.find("cid:" + mid.getId()) != string::npos) { + // This part is referenced in the HTML text. // Add it to the embedded object list. addEmbeddedObject(**p, mid.getId(), embeddedObject::REFERENCED_BY_ID); } } - for (std::vector >::const_iterator p = locParts.begin() ; p != locParts.end() ; ++p) - { + for (std::vector >::const_iterator p = locParts.begin() ; + p != locParts.end() ; ++p) { + const shared_ptr locField = (*p)->getHeader()->findField(fields::CONTENT_LOCATION); const text loc = *locField->getValue (); const string locStr = loc.getWholeBuffer(); - if (data.find(locStr) != string::npos) - { + if (data.find(locStr) != string::npos) { + // This part is referenced in the HTML text. // Add it to the embedded object list. addEmbeddedObject(**p, locStr, embeddedObject::REFERENCED_BY_LOCATION); @@ -244,65 +274,68 @@ void htmlTextPart::parse(const shared_ptr & message, const share } // Extract plain text, if any. - if (!findPlainTextPart(*message, *parent, *textPart)) - { + if (!findPlainTextPart(*message, *parent, *textPart)) { + m_plainText = make_shared (); } } -bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart) -{ +bool htmlTextPart::findPlainTextPart( + const bodyPart& part, + const bodyPart& parent, + const bodyPart& textPart +) { + // We search for the nearest "multipart/alternative" part. const shared_ptr ctf = part.getHeader()->findField(fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + const mediaType type = *ctf->getValue (); if (type.getType() == mediaTypes::MULTIPART && - type.getSubType() == mediaTypes::MULTIPART_ALTERNATIVE) - { + type.getSubType() == mediaTypes::MULTIPART_ALTERNATIVE) { + shared_ptr foundPart; - for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) - { + for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) { + const shared_ptr p = part.getBody()->getPartAt(i); if (p.get() == &parent || // if "text/html" is in "multipart/related" - p.get() == &textPart) // if not... - { + p.get() == &textPart) { // if not... + foundPart = p; } } - if (foundPart) - { + if (foundPart) { + bool found = false; // Now, search for the alternative plain text part - for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) - { + for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) { + const shared_ptr p = part.getBody()->getPartAt(i); const shared_ptr ctf = p->getHeader()->findField(fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { const mediaType type = *ctf->getValue (); if (type.getType() == mediaTypes::TEXT && - type.getSubType() == mediaTypes::TEXT_PLAIN) - { + type.getSubType() == mediaTypes::TEXT_PLAIN) { + m_plainText = p->getBody()->getContents()->clone(); found = true; } - } - else - { + + } else { + // No "Content-type" field. } } @@ -313,16 +346,16 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren return found; } } - } - else - { + + } else { + // No "Content-type" field. } bool found = false; - for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) - { + for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) { + found = findPlainTextPart(*part.getBody()->getPartAt(i), parent, textPart); } @@ -330,50 +363,50 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren } -const charset& htmlTextPart::getCharset() const -{ +const charset& htmlTextPart::getCharset() const { + return m_charset; } -void htmlTextPart::setCharset(const charset& ch) -{ +void htmlTextPart::setCharset(const charset& ch) { + m_charset = ch; } -shared_ptr htmlTextPart::getPlainText() const -{ +shared_ptr htmlTextPart::getPlainText() const { + return m_plainText; } -void htmlTextPart::setPlainText(const shared_ptr & plainText) -{ +void htmlTextPart::setPlainText(const shared_ptr & plainText) { + m_plainText = plainText->clone(); } -const shared_ptr htmlTextPart::getText() const -{ +const shared_ptr htmlTextPart::getText() const { + return m_text; } -void htmlTextPart::setText(const shared_ptr & text) -{ +void htmlTextPart::setText(const shared_ptr & text) { + m_text = text->clone(); } -size_t htmlTextPart::getObjectCount() const -{ +size_t htmlTextPart::getObjectCount() const { + return m_objects.size(); } -shared_ptr htmlTextPart::getObjectAt(const size_t pos) const -{ +shared_ptr htmlTextPart::getObjectAt(const size_t pos) const { + return m_objects[pos]; } @@ -381,36 +414,42 @@ shared_ptr htmlTextPart::getObjectAt(const shared_ptr htmlTextPart::findObject(const string& id) const { for (std::vector >::const_iterator o = m_objects.begin() ; - o != m_objects.end() ; ++o) - { - if ((*o)->matchesId(id)) + o != m_objects.end() ; ++o) { + + if ((*o)->matchesId(id)) { return *o; + } } return null; } -bool htmlTextPart::hasObject(const string& id) const -{ +bool htmlTextPart::hasObject(const string& id) const { + for (std::vector >::const_iterator o = m_objects.begin() ; - o != m_objects.end() ; ++o) - { - if ((*o)->matchesId(id)) + o != m_objects.end() ; ++o) { + + if ((*o)->matchesId(id)) { return true; + } } return false; } -shared_ptr htmlTextPart::addObject - (const shared_ptr & data, const vmime::encoding& enc, const mediaType& type) -{ +shared_ptr htmlTextPart::addObject( + const shared_ptr & data, + const vmime::encoding& enc, + const mediaType& type +) { + const messageId mid(messageId::generateId()); - shared_ptr obj = make_shared - (data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID); + shared_ptr obj = make_shared ( + data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID + ); m_objects.push_back(obj); @@ -418,16 +457,20 @@ shared_ptr htmlTextPart::addObject } -shared_ptr htmlTextPart::addObject - (const shared_ptr & data, const mediaType& type) -{ +shared_ptr htmlTextPart::addObject( + const shared_ptr & data, + const mediaType& type +) { + return addObject(data, encoding::decide(data), type); } -shared_ptr htmlTextPart::addObject - (const string& data, const mediaType& type) -{ +shared_ptr htmlTextPart::addObject( + const string& data, + const mediaType& type +) { + shared_ptr cts = make_shared (data); return addObject(cts, encoding::decide(cts), type); } @@ -438,76 +481,85 @@ shared_ptr htmlTextPart::addObject // htmlTextPart::embeddedObject // -htmlTextPart::embeddedObject::embeddedObject - (const shared_ptr & data, const encoding& enc, - const string& id, const mediaType& type, const ReferenceType refType) +htmlTextPart::embeddedObject::embeddedObject( + const shared_ptr & data, + const encoding& enc, + const string& id, + const mediaType& type, + const ReferenceType refType +) : m_data(vmime::clone(data)), - m_encoding(enc), m_id(id), m_type(type), m_refType(refType) -{ + m_encoding(enc), + m_id(id), + m_type(type), + m_refType(refType) { + } -shared_ptr htmlTextPart::embeddedObject::getData() const -{ +shared_ptr htmlTextPart::embeddedObject::getData() const { + return m_data; } -const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const -{ +const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const { + return m_encoding; } -const string htmlTextPart::embeddedObject::getId() const -{ +const string htmlTextPart::embeddedObject::getId() const { + return m_id; } -const string htmlTextPart::embeddedObject::getReferenceId() const -{ - if (m_refType == REFERENCED_BY_ID) +const string htmlTextPart::embeddedObject::getReferenceId() const { + + if (m_refType == REFERENCED_BY_ID) { return string("cid:") + m_id; - else + } else { return m_id; + } } -const mediaType htmlTextPart::embeddedObject::getType() const -{ +const mediaType htmlTextPart::embeddedObject::getType() const { + return m_type; } -htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const -{ +htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const { + return m_refType; } -bool htmlTextPart::embeddedObject::matchesId(const string& id) const -{ - if (m_refType == REFERENCED_BY_ID) +bool htmlTextPart::embeddedObject::matchesId(const string& id) const { + + if (m_refType == REFERENCED_BY_ID) { return m_id == cleanId(id); - else + } else { return m_id == id; + } } // static -const string htmlTextPart::embeddedObject::cleanId(const string& id) -{ +const string htmlTextPart::embeddedObject::cleanId(const string& id) { + if (id.length() >= 4 && (id[0] == 'c' || id[0] == 'C') && (id[1] == 'i' || id[1] == 'I') && (id[2] == 'd' || id[2] == 'D') && - id[3] == ':') - { + id[3] == ':') { + return id.substr(4); - } - else - { + + } else { + return id; } } diff --git a/src/vmime/htmlTextPart.hpp b/src/vmime/htmlTextPart.hpp index 5ccdf4fa..ac2711b9 100644 --- a/src/vmime/htmlTextPart.hpp +++ b/src/vmime/htmlTextPart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,15 +32,13 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { /** Text part of type 'text/html'. */ +class VMIME_EXPORT htmlTextPart : public textPart { -class VMIME_EXPORT htmlTextPart : public textPart -{ public: htmlTextPart(); @@ -59,13 +57,11 @@ public: /** Embedded object (eg: image for <IMG> tag). */ - class VMIME_EXPORT embeddedObject : public object - { + class VMIME_EXPORT embeddedObject : public object { public: /** The ways embedded objects can be referenced. */ - enum ReferenceType - { + enum ReferenceType { REFERENCED_BY_ID, /**< Referenced by Content-Id. */ REFERENCED_BY_LOCATION /**< Referenced by Content-Location. */ }; @@ -79,9 +75,13 @@ public: * @param refType reference type * @return a reference to a new embedded object */ - embeddedObject(const shared_ptr & data, const encoding& enc, - const string& id, const mediaType& type, - const ReferenceType refType); + embeddedObject( + const shared_ptr & data, + const encoding& enc, + const string& id, + const mediaType& type, + const ReferenceType refType + ); /** Return data stored in this embedded object. * @@ -185,7 +185,10 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - shared_ptr addObject(const string& data, const mediaType& type); + shared_ptr addObject( + const string& data, + const mediaType& type + ); /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -196,7 +199,10 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - shared_ptr addObject(const shared_ptr & data, const mediaType& type); + shared_ptr addObject( + const shared_ptr & data, + const mediaType& type + ); /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -208,13 +214,25 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - shared_ptr addObject(const shared_ptr & data, const encoding& enc, const mediaType& type); + shared_ptr addObject( + const shared_ptr & data, + const encoding& enc, + const mediaType& type + ); size_t getPartCount() const; - void generateIn(const shared_ptr & message, const shared_ptr & parent) const; - void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart); + void generateIn( + const shared_ptr & message, + const shared_ptr & parent + ) const; + + void parse( + const shared_ptr & message, + const shared_ptr & parent, + const shared_ptr & textPart + ); private: @@ -224,10 +242,23 @@ private: std::vector > m_objects; - void findEmbeddedParts(const bodyPart& part, std::vector >& cidParts, std::vector >& locParts); - void addEmbeddedObject(const bodyPart& part, const string& id, const embeddedObject::ReferenceType refType); + void findEmbeddedParts( + const bodyPart& part, + std::vector >& cidParts, + std::vector >& locParts + ); - bool findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart); + void addEmbeddedObject( + const bodyPart& part, + const string& id, + const embeddedObject::ReferenceType refType + ); + + bool findPlainTextPart( + const bodyPart& part, + const bodyPart& parent, + const bodyPart& textPart + ); }; diff --git a/src/vmime/mailbox.cpp b/src/vmime/mailbox.cpp index c4b230c4..b2a577db 100644 --- a/src/vmime/mailbox.cpp +++ b/src/vmime/mailbox.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,30 +26,32 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -namespace vmime -{ +namespace vmime { -mailbox::mailbox() -{ +mailbox::mailbox() { + } mailbox::mailbox(const mailbox& mbox) - : address(), m_name(mbox.m_name), m_email(mbox.m_email) -{ + : address(), + m_name(mbox.m_name), + m_email(mbox.m_email) { + } mailbox::mailbox(const emailAddress& email) - : m_email(email) -{ + : m_email(email) { + } mailbox::mailbox(const text& name, const emailAddress& email) - : m_name(name), m_email(email) -{ + : m_name(name), + m_email(email) { + } @@ -66,10 +68,14 @@ angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr */ -void mailbox::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void mailbox::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; @@ -78,8 +84,7 @@ void mailbox::parseImpl while (p < pend && parserHelpers::isSpace(*p)) ++p; // Current state for parsing machine - enum States - { + enum States { State_None, State_Name, State_Address @@ -92,96 +97,98 @@ void mailbox::parseImpl string address; bool hadBrackets = false; - while (p < pend) - { - if (state == State_Name) - { - if (*p == '<') - { + while (p < pend) { + + if (state == State_Name) { + + if (*p == '<') { + state = State_Address; continue; } - if (*p == '"') // Quoted string - { + if (*p == '"') { // Quoted string + ++p; bool escaped = false; - while (p < pend) - { - if (escaped) - { + while (p < pend) { + + if (escaped) { + name += *p; escaped = false; - } - else if (*p == '\\') - { + + } else if (*p == '\\') { + escaped = true; - } - else - { - if (*p == '"') - { + + } else { + + if (*p == '"') { + ++p; break; - } - else - { + + } else { + name += *p; } } ++p; } - } - else - { + + } else { + bool escaped = false; int comment = 0; - while (p < pend) - { - if (escaped) - { + while (p < pend) { + + if (escaped) { + if (!comment) name += *p; escaped = false; - } - else if (comment) - { - if (*p == '\\') + + } else if (comment) { + + if (*p == '\\') { escaped = true; - else if (*p == '(') + } else if (*p == '(') { ++comment; - else if (*p == ')') + } else if (*p == ')') { --comment; - } - else if (*p == '\\') - { + } + + } else if (*p == '\\') { + escaped = true; - } - else if (*p == '(') - { + + } else if (*p == '(') { + ++comment; - } - else if (*p == '<') - { + + } else if (*p == '<') { + // Erase any space between display name and
string::iterator q = name.end(); - while (q != name.begin() && parserHelpers::isSpace(*(q - 1))) + while (q != name.begin() && parserHelpers::isSpace(*(q - 1))) { --q; + } name.erase(q, name.end()); break; - } - else if (/* parserHelpers::isSpace(*p) || */ *p == '@') - { + + } else if (/* parserHelpers::isSpace(*p) || */ *p == '@') { + break; - } - else - { + + } else { + name += *p; } @@ -189,8 +196,8 @@ void mailbox::parseImpl } } - if (p < pend && *p == '@') - { + if (p < pend && *p == '@') { + // (*) Actually, we were parsing the local-part of an address // and not a display name... address = name; @@ -199,92 +206,94 @@ void mailbox::parseImpl bool escaped = false; int comment = 0; - while (p < pend) - { - if (escaped) - { + while (p < pend) { + + if (escaped) { + if (!comment) address += *p; escaped = false; - } - else if (comment) - { - if (*p == '\\') + + } else if (comment) { + + if (*p == '\\') { escaped = true; - else if (*p == '(') + } else if (*p == '(') { ++comment; - else if (*p == ')') + } else if (*p == ')') { --comment; - } - else if (*p == '\\') - { + } + + } else if (*p == '\\') { + escaped = true; - } - else if (*p == '(') - { + + } else if (*p == '(') { + ++comment; - } - else if (parserHelpers::isSpace(*p)) - { + + } else if (parserHelpers::isSpace(*p)) { + break; - } - else - { + + } else { + address += *p; } ++p; } - } - else - { + + } else { + while (p < pend && parserHelpers::isSpace(*p)) ++p; state = State_None; } - } - else if (state == State_Address) - { + + } else if (state == State_Address) { + bool escaped = false; int comment = 0; - while (p < pend) - { - if (escaped) - { + while (p < pend) { + + if (escaped) { + if (!comment) address += *p; escaped = false; - } - else if (comment) - { - if (*p == '\\') + + } else if (comment) { + + if (*p == '\\') { escaped = true; - else if (*p == '(') + } else if (*p == '(') { ++comment; - else if (*p == ')') + } else if (*p == ')') { --comment; - } - else if (*p == '(') - { + } + + } else if (*p == '(') { + ++comment; - } - else if (*p == '\\') - { + + } else if (*p == '\\') { + escaped = true; - } - else if (*p == '<') - { + + } else if (*p == '<') { + // If we found a '<' here, it means that the address // starts _only_ here...and the stuff we have parsed // before belongs actually to the display name! name += address; address.clear(); - } - else if (*p == '>') - { + + } else if (*p == '>') { + hadBrackets = true; break; - } - else if (!parserHelpers::isSpace(*p)) - { + + } else if (!parserHelpers::isSpace(*p)) { + address += *p; } @@ -292,54 +301,56 @@ void mailbox::parseImpl } break; - } - else - { + + } else { + while (p < pend && parserHelpers::isSpace(*p)) ++p; - if (p < pend) - { - //if (*p == '<') - state = State_Address; + if (p < pend) { + state = State_Address; } } } // Swap name and address when no address was found // (email address is mandatory, whereas name is optional). - if (address.empty() && !name.empty() && !hadBrackets) - { + if (address.empty() && !name.empty() && !hadBrackets) { + m_name.removeAllWords(); m_email.parse(ctx, name); - } - else - { + + } else { + text::decodeAndUnfold(ctx, name, &m_name); m_email.parse(ctx, address); } setParsedBounds(position, position + (p - pstart)); - if (newPosition) + if (newPosition) { *newPosition = position + (p - pstart); + } } -void mailbox::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void mailbox::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + string generatedEmail; utility::outputStreamStringAdapter generatedEmailStream(generatedEmail); m_email.generate(ctx, generatedEmailStream, 0, NULL); - if (m_name.isEmpty()) - { + if (m_name.isEmpty()) { + size_t pos = curLinePos; // No display name is specified, only email address. - if (curLinePos + generatedEmail.length() > ctx.getMaxLineLength()) - { + if (curLinePos + generatedEmail.length() > ctx.getMaxLineLength()) { + os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE.length(); } @@ -347,11 +358,12 @@ void mailbox::generateImpl os << generatedEmail; pos += generatedEmail.length(); - if (newLinePos) + if (newLinePos) { *newLinePos = pos; - } - else - { + } + + } else { + // We have to encode the name: // - if it contains characters in a charset different from "US-ASCII", // - and/or if it contains one or more of these special chars: @@ -361,50 +373,52 @@ void mailbox::generateImpl // and/or contain the special chars. bool forceEncode = false; - for (size_t w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w) - { - if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) - { + for (size_t w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w) { + + if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) { + const string& buffer = m_name.getWordAt(w)->getBuffer(); for (string::const_iterator c = buffer.begin() ; - !forceEncode && c != buffer.end() ; ++c) - { - switch (*c) - { - case '\r': - case '\n': - case '\t': - case ';': - case ',': - case '<': case '>': - case '(': case ')': - case '@': - case '/': - case '?': - case '.': - case '=': - case ':': - case '"': + !forceEncode && c != buffer.end() ; ++c) { - forceEncode = true; - break; + switch (*c) { + + case '\r': + case '\n': + case '\t': + case ';': + case ',': + case '<': case '>': + case '(': case ')': + case '@': + case '/': + case '?': + case '.': + case '=': + case ':': + case '"': + + forceEncode = true; + break; } } - } - else - { + + } else { + forceEncode = true; } } size_t pos = curLinePos; - m_name.encodeAndFold(ctx, os, pos, &pos, - text::QUOTE_IF_POSSIBLE | (forceEncode ? text::FORCE_ENCODING : 0)); + m_name.encodeAndFold( + ctx, os, pos, &pos, + text::QUOTE_IF_POSSIBLE | (forceEncode ? text::FORCE_ENCODING : 0) + ); + + if (pos + generatedEmail.length() + 3 > ctx.getMaxLineLength()) { - if (pos + generatedEmail.length() + 3 > ctx.getMaxLineLength()) - { os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE.length(); } @@ -412,26 +426,27 @@ void mailbox::generateImpl os << " <" << generatedEmail << ">"; pos += 2 + generatedEmail.length() + 1; - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } } -bool mailbox::operator==(const class mailbox& mailbox) const -{ - return (m_name == mailbox.m_name && m_email == mailbox.m_email); +bool mailbox::operator==(const class mailbox& mailbox) const { + + return m_name == mailbox.m_name && m_email == mailbox.m_email; } -bool mailbox::operator!=(const class mailbox& mailbox) const -{ +bool mailbox::operator!=(const class mailbox& mailbox) const { + return !(*this == mailbox); } -void mailbox::copyFrom(const component& other) -{ +void mailbox::copyFrom(const component& other) { + const mailbox& source = dynamic_cast (other); m_name = source.m_name; @@ -439,64 +454,64 @@ void mailbox::copyFrom(const component& other) } -mailbox& mailbox::operator=(const mailbox& other) -{ +mailbox& mailbox::operator=(const mailbox& other) { + copyFrom(other); - return (*this); + return *this; } -shared_ptr mailbox::clone() const -{ +shared_ptr mailbox::clone() const { + return make_shared (*this); } -bool mailbox::isEmpty() const -{ +bool mailbox::isEmpty() const { + return m_email.isEmpty(); } -void mailbox::clear() -{ +void mailbox::clear() { + m_name.removeAllWords(); m_email = emailAddress(); } -bool mailbox::isGroup() const -{ - return (false); +bool mailbox::isGroup() const { + + return false; } -const text& mailbox::getName() const -{ - return (m_name); +const text& mailbox::getName() const { + + return m_name; } -void mailbox::setName(const text& name) -{ +void mailbox::setName(const text& name) { + m_name = name; } -const emailAddress& mailbox::getEmail() const -{ - return (m_email); +const emailAddress& mailbox::getEmail() const { + + return m_email; } -void mailbox::setEmail(const emailAddress& email) -{ +void mailbox::setEmail(const emailAddress& email) { + m_email = email; } -const std::vector > mailbox::getChildComponents() -{ +const std::vector > mailbox::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/mailbox.hpp b/src/vmime/mailbox.hpp index 88abc0f5..c563129d 100644 --- a/src/vmime/mailbox.hpp +++ b/src/vmime/mailbox.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,15 +30,13 @@ #include "vmime/text.hpp" -namespace vmime -{ +namespace vmime { /** A mailbox: full name + email (basic type). */ +class VMIME_EXPORT mailbox : public address { -class VMIME_EXPORT mailbox : public address -{ friend class mailboxGroup; friend class mailboxField; @@ -102,18 +100,20 @@ public: using address::generate; // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/mailboxField.cpp b/src/vmime/mailboxField.cpp index 29fe9d33..82ef5921 100644 --- a/src/vmime/mailboxField.cpp +++ b/src/vmime/mailboxField.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,45 +28,51 @@ #ifndef VMIME_BUILDING_DOC -namespace vmime -{ +namespace vmime { -mailboxField::mailboxField() -{ +mailboxField::mailboxField() { + } mailboxField::mailboxField(const mailboxField&) - : headerField() -{ + : headerField() { + } -void mailboxField::parse - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void mailboxField::parse( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + shared_ptr mbox = make_shared (); // 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... - shared_ptr
parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition, NULL); + shared_ptr
parsedAddress = address::parseNext( + ctx, buffer, position, end, newPosition, NULL + ); + + if (parsedAddress) { + + if (parsedAddress->isGroup()) { - if (parsedAddress) - { - if (parsedAddress->isGroup()) - { // If it is a group of mailboxes, take the first // mailbox of the group shared_ptr group = dynamicCast (parsedAddress); - if (!group->isEmpty()) + if (!group->isEmpty()) { mbox = group->getMailboxAt(0); - } - else - { + } + + } else { + // Parse only if it is a mailbox mbox = dynamicCast (parsedAddress); } @@ -78,8 +84,9 @@ void mailboxField::parse setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } @@ -87,4 +94,3 @@ void mailboxField::parse #endif // VMIME_BUILDING_DOC - diff --git a/src/vmime/mailboxField.hpp b/src/vmime/mailboxField.hpp index ca6863c0..6c653616 100644 --- a/src/vmime/mailboxField.hpp +++ b/src/vmime/mailboxField.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,16 +33,14 @@ #ifndef VMIME_BUILDING_DOC -namespace vmime -{ +namespace vmime { /** Work-around for malformed header fields that are of type 'mailbox' * and contains multiple addresses. */ +class VMIME_EXPORT mailboxField : public headerField { -class VMIME_EXPORT mailboxField : public headerField -{ friend class headerFieldFactory; protected: @@ -52,9 +50,13 @@ protected: public: - void parse(const parsingContext& ctx, const string& buffer, - const size_t position, const size_t end, - size_t * newPosition = NULL); + void parse( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t * newPosition = NULL + ); }; @@ -65,4 +67,3 @@ public: #endif // VMIME_MAILBOXFIELD_HPP_INCLUDED - diff --git a/src/vmime/mailboxGroup.cpp b/src/vmime/mailboxGroup.cpp index 99ca8282..38a6e35e 100644 --- a/src/vmime/mailboxGroup.cpp +++ b/src/vmime/mailboxGroup.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,79 +26,83 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { -mailboxGroup::mailboxGroup() -{ +mailboxGroup::mailboxGroup() { + } mailboxGroup::mailboxGroup(const mailboxGroup& mboxGroup) - : address() -{ + : address() { + copyFrom(mboxGroup); } mailboxGroup::mailboxGroup(const text& name) - : m_name(name) -{ + : m_name(name) { + } -mailboxGroup::~mailboxGroup() -{ +mailboxGroup::~mailboxGroup() { + removeAllMailboxes(); } -void mailboxGroup::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void mailboxGroup::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; - while (p < pend && parserHelpers::isSpace(*p)) + while (p < pend && parserHelpers::isSpace(*p)) { ++p; + } string name; - while (p < pend && *p != ':') - { + while (p < pend && *p != ':') { name += *p; ++p; } - if (p < pend && *p == ':') + if (p < pend && *p == ':') { ++p; + } size_t pos = position + (p - pstart); bool isLastAddressOfGroup = false; - while (pos < end && !isLastAddressOfGroup) - { - shared_ptr
parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup); + while (pos < end && !isLastAddressOfGroup) { + + shared_ptr
parsedAddress = + address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup); + + if (parsedAddress) { + + if (parsedAddress->isGroup()) { - if (parsedAddress) - { - if (parsedAddress->isGroup()) - { shared_ptr group = dynamicCast (parsedAddress); // Sub-groups are not allowed in mailbox groups: so, we add all // the contents of the sub-group into this group... - for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) - { + for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) { m_list.push_back(vmime::clone(group->getMailboxAt(i))); } - } - else - { + + } else { + m_list.push_back(dynamicCast (parsedAddress)); } } @@ -108,15 +112,19 @@ void mailboxGroup::parseImpl setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void mailboxGroup::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void mailboxGroup::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + // We have to encode the name: // - if it contains characters in a charset different from "US-ASCII", // - and/or if it contains one or more of these special chars: @@ -126,32 +134,32 @@ void mailboxGroup::generateImpl // and/or contain the special chars. bool forceEncode = false; - for (size_t w = 0 ; !forceEncode && w < m_name.getWordCount() ; ++w) - { - if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) - { + for (size_t w = 0 ; !forceEncode && w < m_name.getWordCount() ; ++w) { + + if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) { + const string& buffer = m_name.getWordAt(w)->getBuffer(); for (string::const_iterator c = buffer.begin() ; - !forceEncode && c != buffer.end() ; ++c) - { - switch (*c) - { - case ' ': - case '\t': - case ';': - case ',': - case '<': case '>': - case '(': case ')': - case '@': - case '/': - case '?': - case '.': - case '=': - case ':': + !forceEncode && c != buffer.end() ; ++c) { - forceEncode = true; - break; + switch (*c) { + + case ' ': + case '\t': + case ';': + case ',': + case '<': case '>': + case '(': case ')': + case '@': + case '/': + case '?': + case '.': + case '=': + case ':': + + forceEncode = true; + break; } } } @@ -162,22 +170,24 @@ void mailboxGroup::generateImpl generationContext tmpCtx(ctx); tmpCtx.setMaxLineLength(ctx.getMaxLineLength() - 2); - m_name.encodeAndFold(ctx, os, pos, &pos, - forceEncode ? text::FORCE_ENCODING : 0); + m_name.encodeAndFold( + ctx, os, pos, &pos, + forceEncode ? text::FORCE_ENCODING : 0 + ); os << ":"; ++pos; for (std::vector >::const_iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { - if (it != m_list.begin()) - { + it != m_list.end() ; ++it) { + + if (it != m_list.begin()) { + os << ", "; pos += 2; - } - else - { + + } else { + os << " "; ++pos; } @@ -188,13 +198,14 @@ void mailboxGroup::generateImpl os << ";"; pos++; - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } -void mailboxGroup::copyFrom(const component& other) -{ +void mailboxGroup::copyFrom(const component& other) { + const mailboxGroup& source = dynamic_cast (other); m_name = source.m_name; @@ -202,114 +213,132 @@ void mailboxGroup::copyFrom(const component& other) removeAllMailboxes(); for (std::vector >::const_iterator it = source.m_list.begin() ; - it != source.m_list.end() ; ++it) - { + it != source.m_list.end() ; ++it) { + m_list.push_back(vmime::clone(*it)); } } -shared_ptr mailboxGroup::clone() const -{ +shared_ptr mailboxGroup::clone() const { + return make_shared (*this); } -mailboxGroup& mailboxGroup::operator=(const component& other) -{ +mailboxGroup& mailboxGroup::operator=(const component& other) { + copyFrom(other); - return (*this); + return *this; } -const text& mailboxGroup::getName() const -{ - return (m_name); +const text& mailboxGroup::getName() const { + + return m_name; } -void mailboxGroup::setName(const text& name) -{ +void mailboxGroup::setName(const text& name) { + m_name = name; } -bool mailboxGroup::isGroup() const -{ - return (true); +bool mailboxGroup::isGroup() const { + + return true; } -bool mailboxGroup::isEmpty() const -{ - return (m_list.empty()); +bool mailboxGroup::isEmpty() const { + + return m_list.empty(); } -void mailboxGroup::appendMailbox(const shared_ptr & mbox) -{ +void mailboxGroup::appendMailbox(const shared_ptr & mbox) { + m_list.push_back(mbox); } -void mailboxGroup::insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), beforeMailbox); +void mailboxGroup::insertMailboxBefore( + const shared_ptr & beforeMailbox, + const shared_ptr & mbox +) { - if (it == m_list.end()) + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), beforeMailbox); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.insert(it, mbox); } -void mailboxGroup::insertMailboxBefore(const size_t pos, const shared_ptr & mbox) -{ - if (pos >= m_list.size()) +void mailboxGroup::insertMailboxBefore( + const size_t pos, + const shared_ptr & mbox +) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } m_list.insert(m_list.begin() + pos, mbox); } -void mailboxGroup::insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), afterMailbox); +void mailboxGroup::insertMailboxAfter( + const shared_ptr & afterMailbox, + const shared_ptr & mbox +) { - if (it == m_list.end()) + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), afterMailbox); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.insert(it + 1, mbox); } -void mailboxGroup::insertMailboxAfter(const size_t pos, const shared_ptr & mbox) -{ - if (pos >= m_list.size()) +void mailboxGroup::insertMailboxAfter( + const size_t pos, + const shared_ptr & mbox +) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } m_list.insert(m_list.begin() + pos + 1, mbox); } -void mailboxGroup::removeMailbox(const shared_ptr & mbox) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), mbox); +void mailboxGroup::removeMailbox(const shared_ptr & mbox) { - if (it == m_list.end()) + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), mbox); + + if (it == m_list.end()) { throw std::out_of_range("Invalid position"); + } m_list.erase(it); } -void mailboxGroup::removeMailbox(const size_t pos) -{ - if (pos >= m_list.size()) +void mailboxGroup::removeMailbox(const size_t pos) { + + if (pos >= m_list.size()) { throw std::out_of_range("Invalid position"); + } const std::vector >::iterator it = m_list.begin() + pos; @@ -317,59 +346,59 @@ void mailboxGroup::removeMailbox(const size_t pos) } -void mailboxGroup::removeAllMailboxes() -{ +void mailboxGroup::removeAllMailboxes() { + m_list.clear(); } -size_t mailboxGroup::getMailboxCount() const -{ - return (m_list.size()); +size_t mailboxGroup::getMailboxCount() const { + + return m_list.size(); } -shared_ptr mailboxGroup::getMailboxAt(const size_t pos) -{ - return (m_list[pos]); +shared_ptr mailboxGroup::getMailboxAt(const size_t pos) { + + return m_list[pos]; } -const shared_ptr mailboxGroup::getMailboxAt(const size_t pos) const -{ - return (m_list[pos]); +const shared_ptr mailboxGroup::getMailboxAt(const size_t pos) const { + + return m_list[pos]; } -const std::vector > mailboxGroup::getMailboxList() const -{ +const std::vector > mailboxGroup::getMailboxList() const { + std::vector > list; list.reserve(m_list.size()); for (std::vector >::const_iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { + it != m_list.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > mailboxGroup::getMailboxList() -{ - return (m_list); +const std::vector > mailboxGroup::getMailboxList() { + + return m_list; } -const std::vector > mailboxGroup::getChildComponents() -{ +const std::vector > mailboxGroup::getChildComponents() { + std::vector > list; copy_vector(m_list, list); - return (list); + return list; } diff --git a/src/vmime/mailboxGroup.hpp b/src/vmime/mailboxGroup.hpp index 7ae8fd9a..4a7da3e3 100644 --- a/src/vmime/mailboxGroup.hpp +++ b/src/vmime/mailboxGroup.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,15 +30,13 @@ #include "vmime/text.hpp" -namespace vmime -{ +namespace vmime { /** A group of mailboxes (basic type). */ +class VMIME_EXPORT mailboxGroup : public address { -class VMIME_EXPORT mailboxGroup : public address -{ public: mailboxGroup(); @@ -78,7 +76,10 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox); + void insertMailboxBefore( + const shared_ptr & beforeMailbox, + const shared_ptr & mbox + ); /** Insert a new mailbox before the specified position. * @@ -87,7 +88,10 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxBefore(const size_t pos, const shared_ptr & mbox); + void insertMailboxBefore( + const size_t pos, + const shared_ptr & mbox + ); /** Insert a new mailbox after the specified mailbox. * @@ -95,7 +99,10 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the mailbox is not in the list */ - void insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox); + void insertMailboxAfter( + const shared_ptr & afterMailbox, + const shared_ptr & mbox + ); /** Insert a new mailbox after the specified position. * @@ -103,7 +110,10 @@ public: * @param mbox mailbox to insert * @throw std::out_of_range if the position is out of range */ - void insertMailboxAfter(const size_t pos, const shared_ptr & mbox); + void insertMailboxAfter( + const size_t pos, + const shared_ptr & mbox + ); /** Remove the specified mailbox from the list. * @@ -173,18 +183,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/mailboxList.cpp b/src/vmime/mailboxList.cpp index bc99818b..e7aba81b 100644 --- a/src/vmime/mailboxList.cpp +++ b/src/vmime/mailboxList.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,181 +26,198 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { -mailboxList::mailboxList() -{ +mailboxList::mailboxList() { + } mailboxList::mailboxList(const mailboxList& mboxList) - : headerFieldValue(), m_list(mboxList.m_list) -{ + : headerFieldValue(), + m_list(mboxList.m_list) { + } -void mailboxList::appendMailbox(const shared_ptr & mbox) -{ +void mailboxList::appendMailbox(const shared_ptr & mbox) { + m_list.appendAddress(mbox); } -void mailboxList::insertMailboxBefore(const shared_ptr & beforeMailbox, const shared_ptr & mbox) -{ +void mailboxList::insertMailboxBefore( + const shared_ptr & beforeMailbox, + const shared_ptr & mbox +) { + m_list.insertAddressBefore(beforeMailbox, mbox); } -void mailboxList::insertMailboxBefore(const size_t pos, const shared_ptr & mbox) -{ +void mailboxList::insertMailboxBefore( + const size_t pos, + const shared_ptr & mbox +) { + m_list.insertAddressBefore(pos, mbox); } -void mailboxList::insertMailboxAfter(const shared_ptr & afterMailbox, const shared_ptr & mbox) -{ +void mailboxList::insertMailboxAfter( + const shared_ptr & afterMailbox, + const shared_ptr & mbox +) { + m_list.insertAddressAfter(afterMailbox, mbox); } -void mailboxList::insertMailboxAfter(const size_t pos, const shared_ptr & mbox) -{ +void mailboxList::insertMailboxAfter( + const size_t pos, + const shared_ptr & mbox +) { + m_list.insertAddressAfter(pos, mbox); } -void mailboxList::removeMailbox(const shared_ptr & mbox) -{ +void mailboxList::removeMailbox(const shared_ptr & mbox) { + m_list.removeAddress(mbox); } -void mailboxList::removeMailbox(const size_t pos) -{ +void mailboxList::removeMailbox(const size_t pos) { + m_list.removeAddress(pos); } -void mailboxList::removeAllMailboxes() -{ +void mailboxList::removeAllMailboxes() { + m_list.removeAllAddresses(); } -size_t mailboxList::getMailboxCount() const -{ - return (m_list.getAddressCount()); +size_t mailboxList::getMailboxCount() const { + + return m_list.getAddressCount(); } -bool mailboxList::isEmpty() const -{ - return (m_list.isEmpty()); +bool mailboxList::isEmpty() const { + + return m_list.isEmpty(); } -shared_ptr mailboxList::getMailboxAt(const size_t pos) -{ +shared_ptr mailboxList::getMailboxAt(const size_t pos) { + return dynamicCast (m_list.getAddressAt(pos)); } -const shared_ptr mailboxList::getMailboxAt(const size_t pos) const -{ +const shared_ptr mailboxList::getMailboxAt(const size_t pos) const { + return dynamicCast (m_list.getAddressAt(pos)); } -const std::vector > mailboxList::getMailboxList() const -{ +const std::vector > mailboxList::getMailboxList() const { + const std::vector > addrList = m_list.getAddressList(); std::vector > res; for (std::vector >::const_iterator it = addrList.begin() ; - it != addrList.end() ; ++it) - { + it != addrList.end() ; ++it) { + const shared_ptr mbox = dynamicCast (*it); - if (mbox != NULL) + if (mbox) { res.push_back(mbox); + } } - return (res); + return res; } -const std::vector > mailboxList::getMailboxList() -{ +const std::vector > mailboxList::getMailboxList() { + const std::vector > addrList = m_list.getAddressList(); std::vector > res; for (std::vector >::const_iterator it = addrList.begin() ; - it != addrList.end() ; ++it) - { + it != addrList.end() ; ++it) { + const shared_ptr mbox = dynamicCast (*it); - if (mbox != NULL) + if (mbox) { res.push_back(mbox); + } } - return (res); + return res; } -shared_ptr mailboxList::clone() const -{ +shared_ptr mailboxList::clone() const { + return make_shared (*this); } -void mailboxList::copyFrom(const component& other) -{ +void mailboxList::copyFrom(const component& other) { + const mailboxList& mboxList = dynamic_cast (other); m_list = mboxList.m_list; } -mailboxList& mailboxList::operator=(const mailboxList& other) -{ +mailboxList& mailboxList::operator=(const mailboxList& other) { + copyFrom(other); - return (*this); + return *this; } -const std::vector > mailboxList::getChildComponents() -{ - return (m_list.getChildComponents()); +const std::vector > mailboxList::getChildComponents() { + + return m_list.getChildComponents(); } -void mailboxList::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void mailboxList::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_list.removeAllAddresses(); size_t pos = position; - while (pos < end) - { + while (pos < end) { + shared_ptr
parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL); - if (parsedAddress != NULL) - { - if (parsedAddress->isGroup()) - { + if (parsedAddress) { + + if (parsedAddress->isGroup()) { + shared_ptr group = dynamicCast (parsedAddress); - for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) - { + for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) { m_list.appendAddress(group->getMailboxAt(i)); } - } - else - { + + } else { + m_list.appendAddress(parsedAddress); } } @@ -208,20 +225,25 @@ void mailboxList::parseImpl setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void mailboxList::generateImpl(const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void mailboxList::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + m_list.generate(ctx, os, curLinePos, newLinePos); } -shared_ptr mailboxList::toAddressList() const -{ +shared_ptr mailboxList::toAddressList() const { + return vmime::clone(m_list); } diff --git a/src/vmime/mailboxList.hpp b/src/vmime/mailboxList.hpp index aca39136..8d799d2c 100644 --- a/src/vmime/mailboxList.hpp +++ b/src/vmime/mailboxList.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,7 @@ #include "vmime/mailbox.hpp" -namespace vmime -{ +namespace vmime { /** A list of mailboxes (basic type). @@ -38,9 +37,8 @@ namespace vmime * This class works exactly like 'addressList' except it prevents user * from inserting mailbox groups where it is not allowed by the RFC. */ +class VMIME_EXPORT mailboxList : public headerFieldValue { -class VMIME_EXPORT mailboxList : public headerFieldValue -{ public: mailboxList(); @@ -163,18 +161,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/mdn/MDNHelper.cpp b/src/vmime/mdn/MDNHelper.cpp index d416532e..a21a1816 100644 --- a/src/vmime/mdn/MDNHelper.cpp +++ b/src/vmime/mdn/MDNHelper.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,16 +38,16 @@ namespace vmime { namespace mdn { -void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailboxList& mailboxes) -{ +void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailboxList& mailboxes) { + shared_ptr
hdr = msg->getHeader(); hdr->DispositionNotificationTo()->setValue(mailboxes); } -void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailbox& mbox) -{ +void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailbox& mbox) { + mailboxList mboxList; mboxList.appendMailbox(vmime::clone(mbox)); @@ -55,22 +55,23 @@ void MDNHelper::attachMDNRequest(const shared_ptr & msg, const mailbox& } -const std::vector MDNHelper::getPossibleMDNs(const shared_ptr & msg) -{ +const std::vector MDNHelper::getPossibleMDNs(const shared_ptr & msg) { + std::vector result; const shared_ptr hdr = msg->getHeader(); - if (hdr->hasField(fields::DISPOSITION_NOTIFICATION_TO)) - { + if (hdr->hasField(fields::DISPOSITION_NOTIFICATION_TO)) { + const mailboxList& dnto = *hdr->DispositionNotificationTo()->getValue (); - for (size_t i = 0 ; i < dnto.getMailboxCount() ; ++i) + for (size_t i = 0 ; i < dnto.getMailboxCount() ; ++i) { result.push_back(sendableMDNInfos(msg, *dnto.getMailboxAt(i))); + } } - return (result); + return result; } @@ -82,31 +83,32 @@ bool MDNHelper::isMDN(const shared_ptr & msg) // - a Content-Type field is present and its value is "multipart/report" // - a "report-type" parameter is present in the Content-Type field, // and its value is "disposition-notification" - if (hdr->hasField(fields::CONTENT_TYPE)) - { + if (hdr->hasField(fields::CONTENT_TYPE)) { + const contentTypeField& ctf = *dynamicCast (hdr->ContentType()); const mediaType type = *ctf.getValue (); if (type.getType() == vmime::mediaTypes::MULTIPART && - type.getSubType() == vmime::mediaTypes::MULTIPART_REPORT) - { + type.getSubType() == vmime::mediaTypes::MULTIPART_REPORT) { + if (ctf.hasParameter("report-type") && - ctf.getReportType() == "disposition-notification") - { - return (true); + ctf.getReportType() == "disposition-notification") { + + return true; } } } - return (false); + return false; } receivedMDNInfos MDNHelper::getReceivedMDN(const shared_ptr & msg) { - if (!isMDN(msg)) + if (!isMDN(msg)) { throw exceptions::invalid_argument(); + } return receivedMDNInfos(msg); } @@ -117,25 +119,28 @@ bool MDNHelper::needConfirmation(const shared_ptr & msg) shared_ptr hdr = msg->getHeader(); // No "Return-Path" field - if (!hdr->hasField(fields::RETURN_PATH)) + if (!hdr->hasField(fields::RETURN_PATH)) { return true; + } // More than one address in Disposition-Notification-To - if (hdr->hasField(fields::DISPOSITION_NOTIFICATION_TO)) - { + if (hdr->hasField(fields::DISPOSITION_NOTIFICATION_TO)) { + const mailboxList& dnto = *hdr->DispositionNotificationTo()->getValue (); - if (dnto.getMailboxCount() > 1) + if (dnto.getMailboxCount() > 1) { return true; - else if (dnto.getMailboxCount() == 0) + } else if (dnto.getMailboxCount() == 0) { return false; + } // Return-Path != Disposition-Notification-To const mailbox& mbox = *dnto.getMailboxAt(0); const path& rp = *hdr->ReturnPath()->getValue (); - if (mbox.getEmail() != rp.getLocalPart() + "@" + rp.getDomain()) + if (mbox.getEmail() != rp.getLocalPart() + "@" + rp.getDomain()) { return true; + } } // User confirmation not needed @@ -143,23 +148,27 @@ bool MDNHelper::needConfirmation(const shared_ptr & msg) } -shared_ptr MDNHelper::buildMDN(const sendableMDNInfos& mdnInfos, - const string& text, - const charset& ch, - const mailbox& expeditor, - const disposition& dispo, - const string& reportingUA, - const std::vector & reportingUAProducts, - const std::map & fields) -{ +shared_ptr MDNHelper::buildMDN( + const sendableMDNInfos& mdnInfos, + const string& text, + const charset& ch, + const mailbox& expeditor, + const disposition& dispo, + const string& reportingUA, + const std::vector & reportingUAProducts, + const std::map & fields +) { + // Create a new message shared_ptr msg = make_shared (); // Fill-in header fields shared_ptr
hdr = msg->getHeader(); - hdr->ContentType()->setValue(mediaType(vmime::mediaTypes::MULTIPART, - vmime::mediaTypes::MULTIPART_REPORT)); + hdr->ContentType()->setValue( + mediaType(vmime::mediaTypes::MULTIPART, vmime::mediaTypes::MULTIPART_REPORT) + ); + dynamicCast (hdr->ContentType())->setReportType("disposition-notification"); hdr->Disposition()->setValue(dispo); @@ -180,36 +189,42 @@ shared_ptr MDNHelper::buildMDN(const sendableMDNInfos& mdnInfos, dispo, reportingUA, reportingUAProducts, fields)); msg->getBody()->appendPart(createThirdMDNPart(mdnInfos)); - return (msg); + return msg; } -shared_ptr MDNHelper::createFirstMDNPart(const sendableMDNInfos& /* mdnInfos */, - const string& text, const charset& ch) -{ +shared_ptr MDNHelper::createFirstMDNPart( + const sendableMDNInfos& /* mdnInfos */, + const string& text, + const charset& ch +) { + shared_ptr part = make_shared (); // Header shared_ptr
hdr = part->getHeader(); - hdr->ContentType()->setValue(mediaType(vmime::mediaTypes::TEXT, - vmime::mediaTypes::TEXT_PLAIN)); + hdr->ContentType()->setValue( + mediaType(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_PLAIN) + ); dynamicCast (hdr->ContentType())->setCharset(ch); // Body part->getBody()->setContents(make_shared (text)); - return (part); + return part; } -shared_ptr MDNHelper::createSecondMDNPart(const sendableMDNInfos& mdnInfos, - const disposition& dispo, - const string& reportingUA, - const std::vector & reportingUAProducts, - const std::map & additionalFields) -{ +shared_ptr MDNHelper::createSecondMDNPart( + const sendableMDNInfos& mdnInfos, + const disposition& dispo, + const string& reportingUA, + const std::vector & reportingUAProducts, + const std::map & additionalFields +) { + shared_ptr part = make_shared (); // Header @@ -240,17 +255,18 @@ shared_ptr MDNHelper::createSecondMDNPart(const sendableMDNInfos& mdn header fields; // -- Reporting-UA (optional) - if (!reportingUA.empty()) - { + if (!reportingUA.empty()) { + string ruaText; ruaText = reportingUA; - for (unsigned int i = 0 ; i < reportingUAProducts.size() ; ++i) - { - if (i == 0) + for (unsigned int i = 0 ; i < reportingUAProducts.size() ; ++i) { + + if (i == 0) { ruaText += "; "; - else + } else { ruaText += ", "; + } ruaText += reportingUAProducts[i]; } @@ -272,8 +288,8 @@ shared_ptr MDNHelper::createSecondMDNPart(const sendableMDNInfos& mdn fields.appendField(fr); // -- Original-Message-ID - if (mdnInfos.getMessage()->getHeader()->hasField(vmime::fields::MESSAGE_ID)) - { + if (mdnInfos.getMessage()->getHeader()->hasField(vmime::fields::MESSAGE_ID)) { + fields.OriginalMessageId()->setValueConst (mdnInfos.getMessage()->getHeader()->MessageId()->getValue()); } @@ -284,37 +300,30 @@ shared_ptr MDNHelper::createSecondMDNPart(const sendableMDNInfos& mdn // -- Failure, Error and Warning fields std::map ::const_iterator it; - if (additionalFields.size() > 0) - { - it = additionalFields.find(vmime::fields::ERROR); - if (it != additionalFields.end()) - { - shared_ptr error = headerFieldFactory::getInstance()-> - create(vmime::fields::ERROR); + if (additionalFields.size() > 0) { + + if ((it = additionalFields.find(vmime::fields::ERROR)) != additionalFields.end()) { + + shared_ptr error = headerFieldFactory::getInstance()->create(vmime::fields::ERROR); error->setValue(it->second); fields.appendField(error); } - it = additionalFields.find(vmime::fields::WARNING); - if (it != additionalFields.end()) - { - shared_ptr warn = headerFieldFactory::getInstance()-> - create(vmime::fields::WARNING); + if ((it = additionalFields.find(vmime::fields::WARNING)) != additionalFields.end()) { + + shared_ptr warn = headerFieldFactory::getInstance()->create(vmime::fields::WARNING); warn->setValue(it->second); fields.appendField(warn); } - it = additionalFields.find(vmime::fields::FAILURE); - if (it != additionalFields.end()) - { - shared_ptr fail = headerFieldFactory::getInstance()-> - create(vmime::fields::FAILURE); + if ((it = additionalFields.find(vmime::fields::FAILURE)) != additionalFields.end()) { + + shared_ptr fail = headerFieldFactory::getInstance()->create(vmime::fields::FAILURE); fail->setValue(it->second); fields.appendField(fail); } } - std::ostringstream oss; utility::outputStreamAdapter vos(oss); @@ -322,12 +331,12 @@ shared_ptr MDNHelper::createSecondMDNPart(const sendableMDNInfos& mdn part->getBody()->setContents(make_shared (oss.str())); - return (part); + return part; } -shared_ptr MDNHelper::createThirdMDNPart(const sendableMDNInfos& mdnInfos) -{ +shared_ptr MDNHelper::createThirdMDNPart(const sendableMDNInfos& mdnInfos) { + shared_ptr part = make_shared (); // Header @@ -345,7 +354,7 @@ shared_ptr MDNHelper::createThirdMDNPart(const sendableMDNInfos& mdnI part->getBody()->setContents(make_shared (oss.str())); - return (part); + return part; } diff --git a/src/vmime/mdn/MDNHelper.hpp b/src/vmime/mdn/MDNHelper.hpp index d7ba2487..c1bec2f3 100644 --- a/src/vmime/mdn/MDNHelper.hpp +++ b/src/vmime/mdn/MDNHelper.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,9 +38,8 @@ namespace mdn { /** Helper for creating or extracting Message Disposition * Notifications (MDN), as defined in RFC-3798. */ +class VMIME_EXPORT MDNHelper { -class VMIME_EXPORT MDNHelper -{ public: /** Attach a MDN request to the specified message. @@ -105,28 +104,32 @@ public: * @param fields additional MDN fields, like "Error", "Warning" or "Failure" (optional) * @return a new message object containing the MDN */ - static shared_ptr buildMDN(const sendableMDNInfos& mdnInfos, - const string& text, - const charset& ch, - const mailbox& expeditor, - const disposition& dispo, - const string& reportingUA = NULL_STRING, - const std::vector & reportingUAProducts - = std::vector (), - const std::map & fields - = (std::map ())); + static shared_ptr buildMDN( + const sendableMDNInfos& mdnInfos, + const string& text, + const charset& ch, + const mailbox& expeditor, + const disposition& dispo, + const string& reportingUA = NULL_STRING, + const std::vector & reportingUAProducts = std::vector (), + const std::map & fields = std::map () + ); private: - static shared_ptr createFirstMDNPart(const sendableMDNInfos& mdnInfos, - const string& text, const charset& ch); - - static shared_ptr createSecondMDNPart(const sendableMDNInfos& mdnInfos, - const disposition& dispo, - const string& reportingUA, - const std::vector & reportingUAProducts, - const std::map & fields); + static shared_ptr createFirstMDNPart( + const sendableMDNInfos& mdnInfos, + const string& text, + const charset& ch + ); + static shared_ptr createSecondMDNPart( + const sendableMDNInfos& mdnInfos, + const disposition& dispo, + const string& reportingUA, + const std::vector & reportingUAProducts, + const std::map & fields + ); static shared_ptr createThirdMDNPart(const sendableMDNInfos& mdnInfos); }; diff --git a/src/vmime/mdn/MDNInfos.cpp b/src/vmime/mdn/MDNInfos.cpp index a70161b7..3efe9f9f 100644 --- a/src/vmime/mdn/MDNInfos.cpp +++ b/src/vmime/mdn/MDNInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace mdn { -MDNInfos::~MDNInfos() -{ +MDNInfos::~MDNInfos() { + } diff --git a/src/vmime/mdn/MDNInfos.hpp b/src/vmime/mdn/MDNInfos.hpp index 030aa23e..f6d7929b 100644 --- a/src/vmime/mdn/MDNInfos.hpp +++ b/src/vmime/mdn/MDNInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace mdn { /** Holds information about Message Disposition Notifications (MDN). */ +class VMIME_EXPORT MDNInfos : public object { -class VMIME_EXPORT MDNInfos : public object -{ public: virtual ~MDNInfos(); diff --git a/src/vmime/mdn/receivedMDNInfos.cpp b/src/vmime/mdn/receivedMDNInfos.cpp index 6036fcec..6f4463e5 100644 --- a/src/vmime/mdn/receivedMDNInfos.cpp +++ b/src/vmime/mdn/receivedMDNInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,52 +31,52 @@ namespace mdn { receivedMDNInfos::receivedMDNInfos(const shared_ptr & msg) - : m_msg(msg) -{ + : m_msg(msg) { + extract(); } receivedMDNInfos::receivedMDNInfos(const receivedMDNInfos& other) - : MDNInfos() -{ + : MDNInfos() { + copyFrom(other); } -receivedMDNInfos& receivedMDNInfos::operator=(const receivedMDNInfos& other) -{ +receivedMDNInfos& receivedMDNInfos::operator=(const receivedMDNInfos& other) { + copyFrom(other); - return (*this); + return *this; } -const shared_ptr receivedMDNInfos::getMessage() const -{ - return (m_msg); +const shared_ptr receivedMDNInfos::getMessage() const { + + return m_msg; } -const messageId receivedMDNInfos::getOriginalMessageId() const -{ - return (m_omid); +const messageId receivedMDNInfos::getOriginalMessageId() const { + + return m_omid; } -const disposition receivedMDNInfos::getDisposition() const -{ - return (m_disp); +const disposition receivedMDNInfos::getDisposition() const { + + return m_disp; } -const string receivedMDNInfos::getContentMIC() const -{ +const string receivedMDNInfos::getContentMIC() const { + return m_contentMIC; } -void receivedMDNInfos::copyFrom(const receivedMDNInfos& other) -{ +void receivedMDNInfos::copyFrom(const receivedMDNInfos& other) { + m_msg = other.m_msg; m_omid = other.m_omid; m_disp = other.m_disp; @@ -84,23 +84,24 @@ void receivedMDNInfos::copyFrom(const receivedMDNInfos& other) } -void receivedMDNInfos::extract() -{ +void receivedMDNInfos::extract() { + const shared_ptr bdy = m_msg->getBody(); - for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) - { + for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) { + const shared_ptr part = bdy->getPartAt(i); - if (!part->getHeader()->hasField(fields::CONTENT_TYPE)) + if (!part->getHeader()->hasField(fields::CONTENT_TYPE)) { continue; + } const mediaType& type = *part->getHeader()->ContentType()->getValue (); // Extract from second part (message/disposition-notification) if (type.getType() == vmime::mediaTypes::MESSAGE && - type.getSubType() == vmime::mediaTypes::MESSAGE_DISPOSITION_NOTIFICATION) - { + type.getSubType() == vmime::mediaTypes::MESSAGE_DISPOSITION_NOTIFICATION) { + std::ostringstream oss; utility::outputStreamAdapter vos(oss); @@ -113,20 +114,23 @@ void receivedMDNInfos::extract() shared_ptr omid = fields.findFieldValue (fields::ORIGINAL_MESSAGE_ID); - if (omid) + if (omid) { m_omid = *omid; + } shared_ptr disp = fields.findFieldValue (fields::DISPOSITION); - if (disp) + if (disp) { m_disp = *disp; + } shared_ptr contentMIC = fields.findFieldValue ("Received-content-MIC"); - if (contentMIC) + if (contentMIC) { m_contentMIC = contentMIC->generate(); + } } } } diff --git a/src/vmime/mdn/receivedMDNInfos.hpp b/src/vmime/mdn/receivedMDNInfos.hpp index f849a58e..7809acbc 100644 --- a/src/vmime/mdn/receivedMDNInfos.hpp +++ b/src/vmime/mdn/receivedMDNInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,9 +39,8 @@ namespace mdn { /** Holds information about a Message Disposition Notification (MDN) * that has been received. */ +class VMIME_EXPORT receivedMDNInfos : public MDNInfos { -class VMIME_EXPORT receivedMDNInfos : public MDNInfos -{ public: receivedMDNInfos(const shared_ptr & msg); diff --git a/src/vmime/mdn/sendableMDNInfos.cpp b/src/vmime/mdn/sendableMDNInfos.cpp index 85232c1f..281655fb 100644 --- a/src/vmime/mdn/sendableMDNInfos.cpp +++ b/src/vmime/mdn/sendableMDNInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,39 +29,40 @@ namespace mdn { sendableMDNInfos::sendableMDNInfos(const shared_ptr & msg, const mailbox& mbox) - : m_msg(msg), m_mailbox(mbox) -{ + : m_msg(msg), + m_mailbox(mbox) { + } sendableMDNInfos::sendableMDNInfos(const sendableMDNInfos& other) - : MDNInfos() -{ + : MDNInfos() { + copyFrom(other); } -sendableMDNInfos& sendableMDNInfos::operator=(const sendableMDNInfos& other) -{ +sendableMDNInfos& sendableMDNInfos::operator=(const sendableMDNInfos& other) { + copyFrom(other); - return (*this); + return *this; } -const shared_ptr sendableMDNInfos::getMessage() const -{ - return (m_msg); +const shared_ptr sendableMDNInfos::getMessage() const { + + return m_msg; } -const mailbox& sendableMDNInfos::getRecipient() const -{ - return (m_mailbox); +const mailbox& sendableMDNInfos::getRecipient() const { + + return m_mailbox; } -void sendableMDNInfos::copyFrom(const sendableMDNInfos& other) -{ +void sendableMDNInfos::copyFrom(const sendableMDNInfos& other) { + m_msg = other.m_msg; m_mailbox = other.m_mailbox; } diff --git a/src/vmime/mdn/sendableMDNInfos.hpp b/src/vmime/mdn/sendableMDNInfos.hpp index 2c40c3a8..5b69b948 100644 --- a/src/vmime/mdn/sendableMDNInfos.hpp +++ b/src/vmime/mdn/sendableMDNInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,8 @@ namespace mdn { /** Holds information about a Message Disposition Notifications (MDN) * that is to be sent. */ +class VMIME_EXPORT sendableMDNInfos : public MDNInfos { -class VMIME_EXPORT sendableMDNInfos : public MDNInfos -{ public: sendableMDNInfos(const shared_ptr & msg, const mailbox& mbox); diff --git a/src/vmime/mediaType.cpp b/src/vmime/mediaType.cpp index 60486da7..95475937 100644 --- a/src/vmime/mediaType.cpp +++ b/src/vmime/mediaType.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,33 +25,37 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { mediaType::mediaType() - : m_type(mediaTypes::APPLICATION), m_subType(mediaTypes::APPLICATION_OCTET_STREAM) -{ + : m_type(mediaTypes::APPLICATION), + m_subType(mediaTypes::APPLICATION_OCTET_STREAM) { + } -mediaType::mediaType(const string& type) -{ +mediaType::mediaType(const string& type) { + parse(type); } mediaType::mediaType(const string& type, const string& subType) : m_type(utility::stringUtils::toLower(type)), - m_subType(utility::stringUtils::toLower(subType)) -{ + m_subType(utility::stringUtils::toLower(subType)) { + } -void mediaType::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void mediaType::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; @@ -61,79 +65,95 @@ void mediaType::parseImpl while (p < pend && *p != '/') ++p; - m_type = utility::stringUtils::trim(utility::stringUtils::toLower( - string(buffer.begin() + typeStart, - buffer.begin() + position + (p - pstart)))); + m_type = utility::stringUtils::trim( + utility::stringUtils::toLower( + string( + buffer.begin() + typeStart, + buffer.begin() + position + (p - pstart) + ) + ) + ); + + if (p < pend) { - if (p < pend) - { // Skip '/' character ++p; // Extract the sub-type - m_subType = utility::stringUtils::trim(utility::stringUtils::toLower( - string(buffer.begin() + position + (p - pstart), - buffer.begin() + end))); + m_subType = utility::stringUtils::trim( + utility::stringUtils::toLower( + string( + buffer.begin() + position + (p - pstart), + buffer.begin() + end + ) + ) + ); } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void mediaType::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void mediaType::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + const string value = m_type + "/" + m_subType; - if (curLinePos + value.length() > ctx.getMaxLineLength()) - { + if (curLinePos + value.length() > ctx.getMaxLineLength()) { + os << NEW_LINE_SEQUENCE; os << value; - if (newLinePos) + if (newLinePos) { *newLinePos = NEW_LINE_SEQUENCE_LENGTH + value.length(); - } - else - { + } + + } else { + os << value; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + value.length(); + } } } -bool mediaType::operator==(const mediaType& type) const -{ - return (m_type == type.m_type && m_subType == type.m_subType); +bool mediaType::operator==(const mediaType& type) const { + + return m_type == type.m_type && m_subType == type.m_subType; } -bool mediaType::operator!=(const mediaType& type) const -{ +bool mediaType::operator!=(const mediaType& type) const { + return !(*this == type); } -mediaType& mediaType::operator=(const string& type) -{ +mediaType& mediaType::operator=(const string& type) { + parse(type); - return (*this); + return *this; } -shared_ptr mediaType::clone() const -{ +shared_ptr mediaType::clone() const { + return make_shared (m_type, m_subType); } -void mediaType::copyFrom(const component& other) -{ +void mediaType::copyFrom(const component& other) { + const mediaType& mt = dynamic_cast (other); m_type = mt.m_type; @@ -141,45 +161,45 @@ void mediaType::copyFrom(const component& other) } -mediaType& mediaType::operator=(const mediaType& other) -{ +mediaType& mediaType::operator=(const mediaType& other) { + copyFrom(other); - return (*this); + return *this; } -const string& mediaType::getType() const -{ - return (m_type); +const string& mediaType::getType() const { + + return m_type; } -void mediaType::setType(const string& type) -{ +void mediaType::setType(const string& type) { + m_type = utility::stringUtils::toLower(type); } -const string& mediaType::getSubType() const -{ - return (m_subType); +const string& mediaType::getSubType() const { + + return m_subType; } -void mediaType::setSubType(const string& subType) -{ +void mediaType::setSubType(const string& subType) { + m_subType = utility::stringUtils::toLower(subType); } -void mediaType::setFromString(const string& type) -{ +void mediaType::setFromString(const string& type) { + parse(type); } -const std::vector > mediaType::getChildComponents() -{ +const std::vector > mediaType::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/mediaType.hpp b/src/vmime/mediaType.hpp index a7d6f4e4..4026167d 100644 --- a/src/vmime/mediaType.hpp +++ b/src/vmime/mediaType.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** Content media type (basic type). */ +class VMIME_EXPORT mediaType : public headerFieldValue { -class VMIME_EXPORT mediaType : public headerFieldValue -{ public: mediaType(); @@ -98,18 +96,20 @@ protected: string m_subType; // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/message.cpp b/src/vmime/message.cpp index 76735496..f034cdb5 100644 --- a/src/vmime/message.cpp +++ b/src/vmime/message.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,18 +28,19 @@ #include -namespace vmime -{ +namespace vmime { -message::message() -{ +message::message() { + } -const string message::generate - (const size_t maxLineLength, const size_t curLinePos) const -{ +const string message::generate( + const size_t maxLineLength, + const size_t curLinePos +) const { + return bodyPart::generate(maxLineLength, curLinePos); } diff --git a/src/vmime/message.hpp b/src/vmime/message.hpp index 62ff77e1..1b97a5d7 100644 --- a/src/vmime/message.hpp +++ b/src/vmime/message.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/generationContext.hpp" -namespace vmime -{ +namespace vmime { /** A MIME message. */ +class VMIME_EXPORT message : public bodyPart { -class VMIME_EXPORT message : public bodyPart -{ public: message(); @@ -49,13 +47,13 @@ public: // Override default generate() functions so that we can change // the default 'maxLineLength' value - const string generate - (const size_t maxLineLength = generationContext::getDefaultContext().getMaxLineLength(), - const size_t curLinePos = 0) const; + const string generate( + const size_t maxLineLength = generationContext::getDefaultContext().getMaxLineLength(), + const size_t curLinePos = 0 + ) const; }; - } // vmime diff --git a/src/vmime/messageAttachment.hpp b/src/vmime/messageAttachment.hpp index 641fd3e1..2d95d20b 100644 --- a/src/vmime/messageAttachment.hpp +++ b/src/vmime/messageAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/message.hpp" -namespace vmime -{ +namespace vmime { /** Attachment of type message/rfc822. */ +class VMIME_EXPORT messageAttachment : public attachment { -class VMIME_EXPORT messageAttachment : public attachment -{ public: /** Return the message encapsulated in this attachment. @@ -52,4 +50,3 @@ public: #endif // VMIME_MESSAGEATTACHMENT_HPP_INCLUDED - diff --git a/src/vmime/messageBuilder.cpp b/src/vmime/messageBuilder.cpp index 445758c9..4de81bf4 100644 --- a/src/vmime/messageBuilder.cpp +++ b/src/vmime/messageBuilder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -27,24 +27,23 @@ #include "vmime/textPartFactory.hpp" -namespace vmime -{ +namespace vmime { -messageBuilder::messageBuilder() -{ +messageBuilder::messageBuilder() { + // By default there is one text part of type "text/plain" constructTextPart(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); } -messageBuilder::~messageBuilder() -{ +messageBuilder::~messageBuilder() { + } -shared_ptr messageBuilder::construct() const -{ +shared_ptr messageBuilder::construct() const { + // Create a new message shared_ptr msg = make_shared (); @@ -53,22 +52,26 @@ shared_ptr messageBuilder::construct() const if (((m_to.isEmpty()) || (m_to.getAddressAt(0)->isEmpty() && !m_to.getAddressAt(0)->isGroup())) && (m_cc.isEmpty() || m_cc.getAddressAt(0)->isEmpty()) && - (m_bcc.isEmpty() || m_bcc.getAddressAt(0)->isEmpty())) - { + (m_bcc.isEmpty() || m_bcc.getAddressAt(0)->isEmpty())) { + throw exceptions::no_recipient(); } - if (!m_from.isEmpty()) + if (!m_from.isEmpty()) { msg->getHeader()->From()->setValue(m_from); + } - if (!m_to.isEmpty()) + if (!m_to.isEmpty()) { msg->getHeader()->To()->setValue(m_to); + } - if (!m_cc.isEmpty()) + if (!m_cc.isEmpty()) { msg->getHeader()->Cc()->setValue(m_cc); + } - if (!m_bcc.isEmpty()) + if (!m_bcc.isEmpty()) { msg->getHeader()->Bcc()->setValue(m_bcc); + } // Add a "Date" field msg->getHeader()->Date()->setValue(datetime::now()); @@ -94,56 +97,60 @@ shared_ptr messageBuilder::construct() const // | // +-- ... (other attachments/parts) // - if (!m_attach.empty() && m_textPart->getPartCount() > 1) - { + if (!m_attach.empty() && m_textPart->getPartCount() > 1) { + // Set parent part (message) to "multipart/mixed" - msg->getHeader()->ContentType()->setValue - (mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED)); + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED) + ); // Create a sub-part "multipart/alternative" for text parts shared_ptr subPart = make_shared (); msg->getBody()->appendPart(subPart); - subPart->getHeader()->ContentType()->setValue - (mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE)); + subPart->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE) + ); // Generate the text parts into this sub-part (normally, this // sub-part will have the "multipart/alternative" content-type...) m_textPart->generateIn(msg, subPart); - } - else - { + + } else { + // Generate the text part(s) directly into the message m_textPart->generateIn(msg, msg); // If any attachment, set message content-type to "multipart/mixed" - if (!m_attach.empty()) - { - msg->getHeader()->ContentType()->setValue - (mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED)); - } + if (!m_attach.empty()) { + + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED) + ); + // Else, set it to "multipart/alternative" if there are more than one text part. - else if (m_textPart->getPartCount() > 1) - { - msg->getHeader()->ContentType()->setValue - (mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE)); + } else if (m_textPart->getPartCount() > 1) { + + msg->getHeader()->ContentType()->setValue( + mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE) + ); } } // Generate the attachments - if (!m_attach.empty()) - { + if (!m_attach.empty()) { + for (std::vector >::const_iterator a = m_attach.begin() ; - a != m_attach.end() ; ++a) - { + a != m_attach.end() ; ++a) { + (*a)->generateIn(msg); } } // If there is only one part in the message, move it into the message // (hence, the message will not be multipart...) - if (msg->getBody()->getPartCount() == 1) - { + if (msg->getBody()->getPartCount() == 1) { + const bodyPart& part = *msg->getBody()->getPartAt(0); // Make a full copy of the body, otherwise the copyFrom() will delete the body we're copying @@ -153,8 +160,8 @@ shared_ptr messageBuilder::construct() const const std::vector > fields = part.getHeader()->getFieldList(); for (std::vector >::const_iterator it = fields.begin() ; - it != fields.end() ; ++it) - { + it != fields.end() ; ++it) { + *(msg->getHeader()->getField((*it)->getName())) = **it; } @@ -163,32 +170,29 @@ shared_ptr messageBuilder::construct() const msg->getBody()->copyFrom(*bodyCopy); } - return (msg); + return msg; } -void messageBuilder::attach(const shared_ptr & attach) -{ +void messageBuilder::attach(const shared_ptr & attach) { + appendAttachment(attach); } -void messageBuilder::appendAttachment(const shared_ptr & attach) -{ +void messageBuilder::appendAttachment(const shared_ptr & attach) { + m_attach.push_back(attach); } -void messageBuilder::constructTextPart(const mediaType& type) -{ +void messageBuilder::constructTextPart(const mediaType& type) { + shared_ptr part; - try - { + try { part = textPartFactory::getInstance()->create(type); - } - catch (exceptions::no_factory_available& e) - { + } catch (exceptions::no_factory_available& e) { throw; } @@ -196,133 +200,133 @@ void messageBuilder::constructTextPart(const mediaType& type) } -shared_ptr messageBuilder::getTextPart() -{ - return (m_textPart); +shared_ptr messageBuilder::getTextPart() { + + return m_textPart; } -const mailbox& messageBuilder::getExpeditor() const -{ - return (m_from); +const mailbox& messageBuilder::getExpeditor() const { + + return m_from; } -void messageBuilder::setExpeditor(const mailbox& expeditor) -{ +void messageBuilder::setExpeditor(const mailbox& expeditor) { + m_from = expeditor; } -const addressList& messageBuilder::getRecipients() const -{ - return (m_to); +const addressList& messageBuilder::getRecipients() const { + + return m_to; } -addressList& messageBuilder::getRecipients() -{ - return (m_to); +addressList& messageBuilder::getRecipients() { + + return m_to; } -void messageBuilder::setRecipients(const addressList& recipients) -{ +void messageBuilder::setRecipients(const addressList& recipients) { + m_to = recipients; } -const addressList& messageBuilder::getCopyRecipients() const -{ - return (m_cc); +const addressList& messageBuilder::getCopyRecipients() const { + + return m_cc; } -addressList& messageBuilder::getCopyRecipients() -{ - return (m_cc); +addressList& messageBuilder::getCopyRecipients() { + + return m_cc; } -void messageBuilder::setCopyRecipients(const addressList& cc) -{ +void messageBuilder::setCopyRecipients(const addressList& cc) { + m_cc = cc; } -const addressList& messageBuilder::getBlindCopyRecipients() const -{ - return (m_bcc); +const addressList& messageBuilder::getBlindCopyRecipients() const { + + return m_bcc; } -addressList& messageBuilder::getBlindCopyRecipients() -{ - return (m_bcc); +addressList& messageBuilder::getBlindCopyRecipients() { + + return m_bcc; } -void messageBuilder::setBlindCopyRecipients(const addressList& bcc) -{ +void messageBuilder::setBlindCopyRecipients(const addressList& bcc) { + m_bcc = bcc; } -const text& messageBuilder::getSubject() const -{ - return (m_subject); +const text& messageBuilder::getSubject() const { + + return m_subject; } -void messageBuilder::setSubject(const text& subject) -{ +void messageBuilder::setSubject(const text& subject) { + m_subject = subject; } -void messageBuilder::removeAttachment(const size_t pos) -{ +void messageBuilder::removeAttachment(const size_t pos) { + m_attach.erase(m_attach.begin() + pos); } -const shared_ptr messageBuilder::getAttachmentAt(const size_t pos) const -{ - return (m_attach[pos]); +const shared_ptr messageBuilder::getAttachmentAt(const size_t pos) const { + + return m_attach[pos]; } -shared_ptr messageBuilder::getAttachmentAt(const size_t pos) -{ - return (m_attach[pos]); +shared_ptr messageBuilder::getAttachmentAt(const size_t pos) { + + return m_attach[pos]; } -size_t messageBuilder::getAttachmentCount() const -{ - return (m_attach.size()); +size_t messageBuilder::getAttachmentCount() const { + + return m_attach.size(); } -const std::vector > messageBuilder::getAttachmentList() const -{ +const std::vector > messageBuilder::getAttachmentList() const { + std::vector > res; res.reserve(m_attach.size()); for (std::vector >::const_iterator it = m_attach.begin() ; - it != m_attach.end() ; ++it) - { + it != m_attach.end() ; ++it) { + res.push_back(*it); } - return (res); + return res; } -const std::vector > messageBuilder::getAttachmentList() -{ - return (m_attach); +const std::vector > messageBuilder::getAttachmentList() { + + return m_attach; } diff --git a/src/vmime/messageBuilder.hpp b/src/vmime/messageBuilder.hpp index 4b5e15ce..bfe5ed9d 100644 --- a/src/vmime/messageBuilder.hpp +++ b/src/vmime/messageBuilder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,15 +37,13 @@ #include "vmime/bodyPart.hpp" -namespace vmime -{ +namespace vmime { /** A helper for building MIME messages. */ +class VMIME_EXPORT messageBuilder { -class VMIME_EXPORT messageBuilder -{ public: messageBuilder(); diff --git a/src/vmime/messageId.cpp b/src/vmime/messageId.cpp index 18926b4b..c8ea6426 100644 --- a/src/vmime/messageId.cpp +++ b/src/vmime/messageId.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -27,30 +27,32 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { -messageId::messageId() -{ +messageId::messageId() { + } -messageId::messageId(const string& id) -{ +messageId::messageId(const string& id) { + parse(id); } messageId::messageId(const messageId& mid) - : headerFieldValue(), m_left(mid.m_left), m_right(mid.m_right) -{ + : headerFieldValue(), + m_left(mid.m_left), + m_right(mid.m_right) { + } messageId::messageId(const string& left, const string& right) - : m_left(left), m_right(right) -{ + : m_left(left), + m_right(right) { + } @@ -61,10 +63,14 @@ messageId::messageId(const string& left, const string& right) msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS] */ -void messageId::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void messageId::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; @@ -76,27 +82,26 @@ void messageId::parseImpl bool escape = false; bool stop = false; - for ( ; !stop && p < pend ; ++p) - { - if (escape) - { + for ( ; !stop && p < pend ; ++p) { + + if (escape) { + // Ignore this character - } - else - { - switch (*p) - { - case '(': ++commentLevel; break; - case ')': --commentLevel; break; - case '\\': escape = true; break; - case '<': - { - if (commentLevel == 0) - { - stop = true; - break; + + } else { + + switch (*p) { + + case '(': ++commentLevel; break; + case ')': --commentLevel; break; + case '\\': escape = true; break; + case '<': { + + if (commentLevel == 0) { + stop = true; + break; + } } - } } } @@ -105,27 +110,30 @@ void messageId::parseImpl // Fix for message ids without angle brackets (invalid) bool hasBrackets = true; - if (p == pend) // no opening angle bracket found - { + if (p == pend) { // no opening angle bracket found + hasBrackets = false; p = pstart; - while (p < pend && parserHelpers::isSpace(*p)) + while (p < pend && parserHelpers::isSpace(*p)) { ++p; + } } - if (p < pend) - { + if (p < pend) { + // Extract left part const size_t leftStart = position + (p - pstart); while (p < pend && *p != '@' && *p != '>') ++p; - m_left = string(buffer.begin() + leftStart, - buffer.begin() + position + (p - pstart)); + m_left = string( + buffer.begin() + leftStart, + buffer.begin() + position + (p - pstart) + ); + + if (p < pend) { - if (p < pend) - { // Skip '@' ++p; @@ -134,89 +142,110 @@ void messageId::parseImpl while (p < pend && *p != '>' && (hasBrackets || !parserHelpers::isSpace(*p))) ++p; - m_right = string(buffer.begin() + rightStart, - buffer.begin() + position + (p - pstart)); + m_right = string( + buffer.begin() + rightStart, + buffer.begin() + position + (p - pstart) + ); } } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -shared_ptr messageId::parseNext - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +shared_ptr messageId::parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + size_t pos = position; - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } + + if (pos != end) { - if (pos != end) - { const size_t begin = pos; - while (pos < end && !parserHelpers::isSpace(buffer[pos])) + while (pos < end && !parserHelpers::isSpace(buffer[pos])) { ++pos; + } shared_ptr mid = make_shared (); mid->parse(ctx, buffer, begin, pos, NULL); - if (newPosition != NULL) + if (newPosition) { *newPosition = pos; + } - return (mid); + return mid; } - if (newPosition != NULL) + if (newPosition) { *newPosition = end; + } return null; } -const string messageId::getId() const -{ - if (m_right.empty()) - return m_left; +const string messageId::getId() const { - return (m_left + '@' + m_right); + if (m_right.empty()) { + return m_left; + } + + return m_left + '@' + m_right; } -void messageId::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void messageId::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + size_t pos = curLinePos; - if (ctx.getWrapMessageId() && (curLinePos + m_left.length() + m_right.length() + 3 > ctx.getMaxLineLength())) - { + if (ctx.getWrapMessageId() && + (curLinePos + m_left.length() + m_right.length() + 3 > ctx.getMaxLineLength())) { + os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE_LENGTH; } os << '<' << m_left; - if (m_right != "") os << '@' << m_right; + + if (m_right != "") { + os << '@' << m_right; + } + os << '>'; - if (newLinePos) + if (newLinePos) { *newLinePos = pos + m_left.length() + m_right.length() + 3; + } } -messageId& messageId::operator=(const string& id) -{ +messageId& messageId::operator=(const string& id) { + parse(id); - return (*this); + return *this; } -messageId messageId::generateId() -{ +messageId messageId::generateId() { + std::ostringstream left; left.imbue(std::locale::classic()); @@ -229,30 +258,30 @@ messageId messageId::generateId() left << std::hex << utility::random::getNext(); left << std::hex << utility::random::getNext(); - return (messageId(left.str(), platform::getHandler()->getHostName())); + return messageId(left.str(), platform::getHandler()->getHostName()); } -bool messageId::operator==(const messageId& mid) const -{ - return (m_left == mid.m_left && m_right == mid.m_right); +bool messageId::operator==(const messageId& mid) const { + + return m_left == mid.m_left && m_right == mid.m_right; } -bool messageId::operator!=(const messageId& mid) const -{ +bool messageId::operator!=(const messageId& mid) const { + return !(*this == mid); } -shared_ptr messageId::clone() const -{ +shared_ptr messageId::clone() const { + return make_shared (*this); } -void messageId::copyFrom(const component& other) -{ +void messageId::copyFrom(const component& other) { + const messageId& mid = dynamic_cast (other); m_left = mid.m_left; @@ -260,39 +289,39 @@ void messageId::copyFrom(const component& other) } -messageId& messageId::operator=(const messageId& other) -{ +messageId& messageId::operator=(const messageId& other) { + copyFrom(other); - return (*this); + return *this; } -const string& messageId::getLeft() const -{ - return (m_left); +const string& messageId::getLeft() const { + + return m_left; } -void messageId::setLeft(const string& left) -{ +void messageId::setLeft(const string& left) { + m_left = left; } -const string& messageId::getRight() const -{ - return (m_right); +const string& messageId::getRight() const { + + return m_right; } -void messageId::setRight(const string& right) -{ +void messageId::setRight(const string& right) { + m_right = right; } -const std::vector > messageId::getChildComponents() -{ +const std::vector > messageId::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/messageId.hpp b/src/vmime/messageId.hpp index 83527468..8edbe3e3 100644 --- a/src/vmime/messageId.hpp +++ b/src/vmime/messageId.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,15 +29,13 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** Message identifier (basic type). */ +class VMIME_EXPORT messageId : public headerFieldValue { -class VMIME_EXPORT messageId : public headerFieldValue -{ friend class messageIdSequence; public: @@ -107,18 +105,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; /** Parse a message-id from an input buffer. * @@ -128,12 +128,13 @@ protected: * @param newPosition will receive the new position in the input buffer * @return a new message-id object, or null if no more message-id can be parsed from the input buffer */ - static shared_ptr parseNext - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition); + static shared_ptr parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition + ); }; diff --git a/src/vmime/messageIdSequence.cpp b/src/vmime/messageIdSequence.cpp index 4365fa3c..2b68bcc7 100644 --- a/src/vmime/messageIdSequence.cpp +++ b/src/vmime/messageIdSequence.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -23,229 +23,254 @@ #include "vmime/messageIdSequence.hpp" #include "vmime/exception.hpp" + #include -namespace vmime -{ +namespace vmime { +messageIdSequence::messageIdSequence() { - -messageIdSequence::messageIdSequence() -{ } -messageIdSequence::~messageIdSequence() -{ +messageIdSequence::~messageIdSequence() { + removeAllMessageIds(); } messageIdSequence::messageIdSequence(const messageIdSequence& midSeq) - : headerFieldValue() -{ + : headerFieldValue() { + copyFrom(midSeq); } -shared_ptr messageIdSequence::clone() const -{ +shared_ptr messageIdSequence::clone() const { + return make_shared (*this); } -void messageIdSequence::copyFrom(const component& other) -{ +void messageIdSequence::copyFrom(const component& other) { + const messageIdSequence& midSeq = dynamic_cast (other); removeAllMessageIds(); - for (unsigned int i = 0 ; i < midSeq.m_list.size() ; ++i) + for (unsigned int i = 0 ; i < midSeq.m_list.size() ; ++i) { m_list.push_back(vmime::clone(midSeq.m_list[i])); + } } -messageIdSequence& messageIdSequence::operator=(const messageIdSequence& other) -{ +messageIdSequence& messageIdSequence::operator=(const messageIdSequence& other) { + copyFrom(other); - return (*this); + return *this; } -const std::vector > messageIdSequence::getChildComponents() -{ +const std::vector > messageIdSequence::getChildComponents() { + std::vector > res; copy_vector(m_list, res); - return (res); + return res; } -void messageIdSequence::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void messageIdSequence::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + removeAllMessageIds(); size_t pos = position; - while (pos < end) - { + while (pos < end) { + shared_ptr parsedMid = messageId::parseNext(ctx, buffer, pos, end, &pos); - if (parsedMid != NULL) + if (parsedMid) { m_list.push_back(parsedMid); + } } setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void messageIdSequence::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void messageIdSequence::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + size_t pos = curLinePos; - if (!m_list.empty()) - { + if (!m_list.empty()) { + generationContext tmpCtx(ctx); tmpCtx.setMaxLineLength(ctx.getMaxLineLength() - 2); - for (std::vector >::const_iterator it = m_list.begin() ; ; ) - { + for (std::vector >::const_iterator it = m_list.begin() ; ; ) { + (*it)->generate(ctx, os, pos, &pos); - if (++it == m_list.end()) + if (++it == m_list.end()) { break; + } os << " "; pos++; } } - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } -void messageIdSequence::appendMessageId(const shared_ptr & mid) -{ +void messageIdSequence::appendMessageId(const shared_ptr & mid) { + m_list.push_back(mid); } -void messageIdSequence::insertMessageIdBefore(const shared_ptr & beforeMid, const shared_ptr & mid) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), beforeMid); +void messageIdSequence::insertMessageIdBefore( + const shared_ptr & beforeMid, + const shared_ptr & mid +) { - if (it == m_list.end()) + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), beforeMid); + + if (it == m_list.end()) { throw exceptions::no_such_message_id(); + } m_list.insert(it, mid); } -void messageIdSequence::insertMessageIdBefore(const size_t pos, const shared_ptr & mid) -{ +void messageIdSequence::insertMessageIdBefore( + const size_t pos, + const shared_ptr & mid +) { + m_list.insert(m_list.begin() + pos, mid); } -void messageIdSequence::insertMessageIdAfter(const shared_ptr & afterMid, const shared_ptr & mid) -{ - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), afterMid); +void messageIdSequence::insertMessageIdAfter( + const shared_ptr & afterMid, + const shared_ptr & mid +) { - if (it == m_list.end()) + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), afterMid); + + if (it == m_list.end()) { throw exceptions::no_such_message_id(); + } m_list.insert(it + 1, mid); } -void messageIdSequence::insertMessageIdAfter(const size_t pos, const shared_ptr & mid) -{ +void messageIdSequence::insertMessageIdAfter( + const size_t pos, + const shared_ptr & mid +) { + m_list.insert(m_list.begin() + pos + 1, mid); } void messageIdSequence::removeMessageId(const shared_ptr & mid) { - const std::vector >::iterator it = std::find - (m_list.begin(), m_list.end(), mid); + const std::vector >::iterator it = + std::find(m_list.begin(), m_list.end(), mid); - if (it == m_list.end()) + if (it == m_list.end()) { throw exceptions::no_such_message_id(); + } m_list.erase(it); } -void messageIdSequence::removeMessageId(const size_t pos) -{ +void messageIdSequence::removeMessageId(const size_t pos) { + const std::vector >::iterator it = m_list.begin() + pos; m_list.erase(it); } -void messageIdSequence::removeAllMessageIds() -{ +void messageIdSequence::removeAllMessageIds() { + m_list.clear(); } -size_t messageIdSequence::getMessageIdCount() const -{ - return (m_list.size()); +size_t messageIdSequence::getMessageIdCount() const { + + return m_list.size(); } -bool messageIdSequence::isEmpty() const -{ - return (m_list.empty()); +bool messageIdSequence::isEmpty() const { + + return m_list.empty(); } -const shared_ptr messageIdSequence::getMessageIdAt(const size_t pos) -{ - return (m_list[pos]); +const shared_ptr messageIdSequence::getMessageIdAt(const size_t pos) { + + return m_list[pos]; } -const shared_ptr messageIdSequence::getMessageIdAt(const size_t pos) const -{ - return (m_list[pos]); +const shared_ptr messageIdSequence::getMessageIdAt(const size_t pos) const { + + return m_list[pos]; } -const std::vector > messageIdSequence::getMessageIdList() const -{ +const std::vector > messageIdSequence::getMessageIdList() const { + std::vector > list; list.reserve(m_list.size()); for (std::vector >::const_iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { + it != m_list.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > messageIdSequence::getMessageIdList() -{ - return (m_list); +const std::vector > messageIdSequence::getMessageIdList() { + + return m_list; } diff --git a/src/vmime/messageIdSequence.hpp b/src/vmime/messageIdSequence.hpp index b0eea464..e5d0eb64 100644 --- a/src/vmime/messageIdSequence.hpp +++ b/src/vmime/messageIdSequence.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/messageId.hpp" -namespace vmime -{ +namespace vmime { /** A list of message identifiers (basic type). */ +class VMIME_EXPORT messageIdSequence : public headerFieldValue { -class VMIME_EXPORT messageIdSequence : public headerFieldValue -{ public: messageIdSequence(); @@ -80,7 +78,10 @@ public: * @param mid message-id to insert * @throw exceptions::no_such_message_id if the message-id is not in the list */ - void insertMessageIdAfter(const shared_ptr & afterMid, const shared_ptr & mid); + void insertMessageIdAfter( + const shared_ptr & afterMid, + const shared_ptr & mid + ); /** Insert a new message-id after the specified position. * @@ -151,18 +152,20 @@ private: protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/messageParser.cpp b/src/vmime/messageParser.cpp index c5295504..21ac09bb 100644 --- a/src/vmime/messageParser.cpp +++ b/src/vmime/messageParser.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,12 +33,11 @@ #include "vmime/contentDispositionField.hpp" -namespace vmime -{ +namespace vmime { -messageParser::messageParser(const string& buffer) -{ +messageParser::messageParser(const string& buffer) { + shared_ptr msg = make_shared (); msg->parse(buffer); @@ -46,27 +45,27 @@ messageParser::messageParser(const string& buffer) } -messageParser::messageParser(const shared_ptr & msg) -{ +messageParser::messageParser(const shared_ptr & msg) { + parse(msg); } -messageParser::~messageParser() -{ +messageParser::~messageParser() { + } -void messageParser::parse(const shared_ptr & msg) -{ +void messageParser::parse(const shared_ptr & msg) { + // Header fields (if field is present, copy its value, else do nothing) #ifndef VMIME_BUILDING_DOC -#define TRY_FIELD(var, type, name) \ - { \ +#define TRY_FIELD(var, type, name) { \ shared_ptr fldValue = msg->getHeader()->findFieldValue (name); \ - if (fldValue) \ + if (fldValue) { \ var = *fldValue; \ + } \ } TRY_FIELD(m_from, mailbox, fields::FROM); @@ -84,18 +83,19 @@ void messageParser::parse(const shared_ptr & msg) // Date shared_ptr recv = msg->getHeader()->findField(fields::RECEIVED); - if (recv) - { + if (recv) { + m_date = recv->getValue ()->getDate(); - } - else - { + + } else { + shared_ptr date = msg->getHeader()->findField(fields::DATE); - if (date) + if (date) { m_date = *date->getValue (); - else + } else { m_date = datetime::now(); + } } // Attachments @@ -106,58 +106,64 @@ void messageParser::parse(const shared_ptr & msg) } -void messageParser::findAttachments(const shared_ptr & msg) -{ +void messageParser::findAttachments(const shared_ptr & msg) { + m_attach = attachmentHelper::findAttachmentsInMessage(msg); } -void messageParser::findTextParts(const shared_ptr & msg, const shared_ptr & part) -{ +void messageParser::findTextParts( + const shared_ptr & msg, + const shared_ptr & part +) { + // Handle the case in which the message is not multipart: if the body part is // "text/*", take this part. - if (part->getBody()->getPartCount() == 0) - { + if (part->getBody()->getPartCount() == 0) { + mediaType type(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN); bool accept = false; shared_ptr ctf = msg->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + const mediaType ctfType = *ctf->getValue (); - if (ctfType.getType() == mediaTypes::TEXT) - { + if (ctfType.getType() == mediaTypes::TEXT) { + type = ctfType; accept = true; } - } - else - { + + } else { + // No "Content-type" field: assume "text/plain". accept = true; } - if (accept) - { + if (accept) { + shared_ptr txtPart = textPartFactory::getInstance()->create(type); txtPart->parse(msg, msg, msg); m_textParts.push_back(txtPart); } - } + // Multipart message - else - { + } else { + findSubTextParts(msg, part); } } -bool messageParser::findSubTextParts(const shared_ptr & msg, const shared_ptr & part) -{ +bool messageParser::findSubTextParts( + const shared_ptr & msg, + const shared_ptr & part +) { + // In general, all the text parts are contained in parallel in the same // parent part (or message). // So, wherever the text parts are, all we have to do is to find the first @@ -165,62 +171,63 @@ bool messageParser::findSubTextParts(const shared_ptr & msg, con std::vector > textParts; - for (size_t i = 0 ; i < part->getBody()->getPartCount() ; ++i) - { + for (size_t i = 0 ; i < part->getBody()->getPartCount() ; ++i) { + const shared_ptr p = part->getBody()->getPartAt(i); shared_ptr ctf = p->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf) - { + if (ctf) { + const mediaType type = *ctf->getValue (); contentDisposition disp; // default should be inline - if (type.getType() == mediaTypes::TEXT) - { + if (type.getType() == mediaTypes::TEXT) { + shared_ptr cdf = p->getHeader()-> findField (fields::CONTENT_DISPOSITION); - if (cdf) - { + if (cdf) { + disp = *cdf->getValue (); - } - else - { + + } else { + // No "Content-Disposition" field, assume default } - if (disp.getName() == contentDispositionTypes::INLINE) + if (disp.getName() == contentDispositionTypes::INLINE) { textParts.push_back(p); + } } - } - else - { + + } else { + // No "Content-type" field. } } - if (textParts.size()) - { + if (textParts.size()) { + // Okay. So we have found at least one text part for (std::vector >::const_iterator p = textParts.begin() ; - p != textParts.end() ; ++p) - { + p != textParts.end() ; ++p) { + const contentTypeField& ctf = *(*p)->getHeader()->findField (fields::CONTENT_TYPE); const mediaType type = *ctf.getValue (); - try - { + try { + shared_ptr txtPart = textPartFactory::getInstance()->create(type); txtPart->parse(msg, part, *p); m_textParts.push_back(txtPart); - } - catch (exceptions::no_factory_available& e) - { + + } catch (exceptions::no_factory_available& e) { + // Content-type not recognized. } } @@ -228,8 +235,7 @@ bool messageParser::findSubTextParts(const shared_ptr & msg, con bool found = false; - for (size_t i = 0 ; !found && (i < part->getBody()->getPartCount()) ; ++i) - { + for (size_t i = 0 ; !found && (i < part->getBody()->getPartCount()) ; ++i) { found = findSubTextParts(msg, part->getBody()->getPartAt(i)); } @@ -237,85 +243,85 @@ bool messageParser::findSubTextParts(const shared_ptr & msg, con } -const mailbox& messageParser::getExpeditor() const -{ - return (m_from); +const mailbox& messageParser::getExpeditor() const { + + return m_from; } -const addressList& messageParser::getRecipients() const -{ - return (m_to); +const addressList& messageParser::getRecipients() const { + + return m_to; } -const addressList& messageParser::getCopyRecipients() const -{ - return (m_cc); +const addressList& messageParser::getCopyRecipients() const { + + return m_cc; } -const addressList& messageParser::getBlindCopyRecipients() const -{ - return (m_bcc); +const addressList& messageParser::getBlindCopyRecipients() const { + + return m_bcc; } -const text& messageParser::getSubject() const -{ - return (m_subject); +const text& messageParser::getSubject() const { + + return m_subject; } -const datetime& messageParser::getDate() const -{ - return (m_date); +const datetime& messageParser::getDate() const { + + return m_date; } -const std::vector > messageParser::getAttachmentList() const -{ +const std::vector > messageParser::getAttachmentList() const { + return m_attach; } -size_t messageParser::getAttachmentCount() const -{ - return (m_attach.size()); +size_t messageParser::getAttachmentCount() const { + + return m_attach.size(); } -const shared_ptr messageParser::getAttachmentAt(const size_t pos) const -{ - return (m_attach[pos]); +const shared_ptr messageParser::getAttachmentAt(const size_t pos) const { + + return m_attach[pos]; } -const std::vector > messageParser::getTextPartList() const -{ +const std::vector > messageParser::getTextPartList() const { + std::vector > res; res.reserve(m_textParts.size()); for (std::vector >::const_iterator it = m_textParts.begin() ; - it != m_textParts.end() ; ++it) - { + it != m_textParts.end() ; ++it) { + res.push_back(*it); } - return (res); + return res; } -size_t messageParser::getTextPartCount() const -{ - return (m_textParts.size()); +size_t messageParser::getTextPartCount() const { + + return m_textParts.size(); } -const shared_ptr messageParser::getTextPartAt(const size_t pos) const -{ - return (m_textParts[pos]); +const shared_ptr messageParser::getTextPartAt(const size_t pos) const { + + return m_textParts[pos]; } diff --git a/src/vmime/messageParser.hpp b/src/vmime/messageParser.hpp index 5413862d..8019ef37 100644 --- a/src/vmime/messageParser.hpp +++ b/src/vmime/messageParser.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,15 +37,13 @@ #include "vmime/textPart.hpp" -namespace vmime -{ +namespace vmime { /** A helper for parsing MIME messages. */ +class VMIME_EXPORT messageParser { -class VMIME_EXPORT messageParser -{ public: messageParser(const string& buffer); @@ -148,8 +146,15 @@ private: void findAttachments(const shared_ptr & msg); - void findTextParts(const shared_ptr & msg, const shared_ptr & part); - bool findSubTextParts(const shared_ptr & msg, const shared_ptr & part); + void findTextParts( + const shared_ptr & msg, + const shared_ptr & part + ); + + bool findSubTextParts( + const shared_ptr & msg, + const shared_ptr & part + ); }; diff --git a/src/vmime/misc/importanceHelper.cpp b/src/vmime/misc/importanceHelper.cpp index ac298619..20c8e13b 100644 --- a/src/vmime/misc/importanceHelper.cpp +++ b/src/vmime/misc/importanceHelper.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,14 +31,14 @@ namespace vmime { namespace misc { -void importanceHelper::resetImportance(const shared_ptr & msg) -{ +void importanceHelper::resetImportance(const shared_ptr & msg) { + resetImportanceHeader(msg->getHeader()); } -void importanceHelper::resetImportanceHeader(const shared_ptr
& hdr) -{ +void importanceHelper::resetImportanceHeader(const shared_ptr
& hdr) { + shared_ptr fld; if ((fld = hdr->findField("X-Priority"))) @@ -49,19 +49,19 @@ void importanceHelper::resetImportanceHeader(const shared_ptr
& hdr) } -importanceHelper::Importance importanceHelper::getImportance(const shared_ptr & msg) -{ +importanceHelper::Importance importanceHelper::getImportance(const shared_ptr & msg) { + return getImportanceHeader(msg->getHeader()); } -importanceHelper::Importance importanceHelper::getImportanceHeader(const shared_ptr & hdr) -{ +importanceHelper::Importance importanceHelper::getImportanceHeader(const shared_ptr & hdr) { + // Try "X-Priority" field shared_ptr fld = hdr->findField("X-Priority"); - if (fld) - { + if (fld) { + const string value = fld->getValue ()->getWholeBuffer(); int n = IMPORTANCE_NORMAL; @@ -73,89 +73,88 @@ importanceHelper::Importance importanceHelper::getImportanceHeader(const shared_ Importance i = IMPORTANCE_NORMAL; - switch (n) - { - case 1: i = IMPORTANCE_HIGHEST; break; - case 2: i = IMPORTANCE_HIGH; break; - case 3: i = IMPORTANCE_NORMAL; break; - case 4: i = IMPORTANCE_LOW; break; - case 5: i = IMPORTANCE_LOWEST; break; + switch (n) { + case 1: i = IMPORTANCE_HIGHEST; break; + case 2: i = IMPORTANCE_HIGH; break; + case 3: i = IMPORTANCE_NORMAL; break; + case 4: i = IMPORTANCE_LOW; break; + case 5: i = IMPORTANCE_LOWEST; break; } - return (i); - } - else - { + return i; + + } else { + // Try "Importance" field fld = hdr->findField("Importance"); - if (fld) - { + if (fld) { + const string value = utility::stringUtils::toLower(utility::stringUtils::trim (fld->getValue ()->getWholeBuffer())); - if (value == "low") - return (IMPORTANCE_LOWEST); - else if (value == "high") - return (IMPORTANCE_HIGHEST); - else - return (IMPORTANCE_NORMAL); - } - else - { + if (value == "low") { + return IMPORTANCE_LOWEST; + } else if (value == "high") { + return IMPORTANCE_HIGHEST; + } else { + return IMPORTANCE_NORMAL; + } + + } else { + // Default - return (IMPORTANCE_NORMAL); + return IMPORTANCE_NORMAL; } } // Should not go here... - return (IMPORTANCE_NORMAL); + return IMPORTANCE_NORMAL; } -void importanceHelper::setImportance(const shared_ptr & msg, const Importance i) -{ +void importanceHelper::setImportance(const shared_ptr & msg, const Importance i) { + setImportanceHeader(msg->getHeader(), i); } -void importanceHelper::setImportanceHeader(const shared_ptr
& hdr, const Importance i) -{ +void importanceHelper::setImportanceHeader(const shared_ptr
& hdr, const Importance i) { + // "X-Priority:" Field shared_ptr fld = hdr->getField("X-Priority"); - switch (i) - { - case IMPORTANCE_HIGHEST: fld->setValue("1 (Highest)"); break; - case IMPORTANCE_HIGH: fld->setValue("2 (High)"); break; - default: - case IMPORTANCE_NORMAL: fld->setValue("3 (Normal)"); break; - case IMPORTANCE_LOW: fld->setValue("4 (Low)"); break; - case IMPORTANCE_LOWEST: fld->setValue("5 (Lowest)"); break; + switch (i) { + case IMPORTANCE_HIGHEST: fld->setValue("1 (Highest)"); break; + case IMPORTANCE_HIGH: fld->setValue("2 (High)"); break; + default: + case IMPORTANCE_NORMAL: fld->setValue("3 (Normal)"); break; + case IMPORTANCE_LOW: fld->setValue("4 (Low)"); break; + case IMPORTANCE_LOWEST: fld->setValue("5 (Lowest)"); break; } // "Importance:" Field fld = hdr->getField("Importance"); - switch (i) - { - case IMPORTANCE_HIGHEST: - case IMPORTANCE_HIGH: + switch (i) { - fld->setValue("high"); - break; + case IMPORTANCE_HIGHEST: + case IMPORTANCE_HIGH: - default: - case IMPORTANCE_NORMAL: + fld->setValue("high"); + break; - fld->setValue("normal"); - break; + default: + case IMPORTANCE_NORMAL: - case IMPORTANCE_LOWEST: - case IMPORTANCE_LOW: + fld->setValue("normal"); + break; - fld->setValue("low"); - break; + case IMPORTANCE_LOWEST: + case IMPORTANCE_LOW: + + fld->setValue("low"); + break; } } diff --git a/src/vmime/misc/importanceHelper.hpp b/src/vmime/misc/importanceHelper.hpp index 18dc2364..45e0bcc7 100644 --- a/src/vmime/misc/importanceHelper.hpp +++ b/src/vmime/misc/importanceHelper.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,14 +38,12 @@ namespace misc { * Basically, it wraps the use of the 'X-Priority' (non standard) * and 'Importance' (RFC-1327, RFC-1911) fields. */ +class VMIME_EXPORT importanceHelper { -class VMIME_EXPORT importanceHelper -{ public: /** Different levels of importance. */ - enum Importance - { + enum Importance { IMPORTANCE_HIGHEST, IMPORTANCE_HIGH, IMPORTANCE_NORMAL, diff --git a/src/vmime/net/builtinServices.inl b/src/vmime/net/builtinServices.inl index fa2f3fe3..2f67d2e0 100644 --- a/src/vmime/net/builtinServices.inl +++ b/src/vmime/net/builtinServices.inl @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/connectionInfos.hpp b/src/vmime/net/connectionInfos.hpp index 6c86eeab..0e519c7e 100644 --- a/src/vmime/net/connectionInfos.hpp +++ b/src/vmime/net/connectionInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ namespace net { /** Information about the connection used by a service. */ -class VMIME_EXPORT connectionInfos : public object -{ +class VMIME_EXPORT connectionInfos : public object { + public: /** Return the host to which the service is connected. diff --git a/src/vmime/net/defaultConnectionInfos.cpp b/src/vmime/net/defaultConnectionInfos.cpp index 335e8f6f..889f214a 100644 --- a/src/vmime/net/defaultConnectionInfos.cpp +++ b/src/vmime/net/defaultConnectionInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,19 +35,19 @@ namespace net { defaultConnectionInfos::defaultConnectionInfos(const string& host, const port_t port) - : m_host(host), m_port(port) -{ + : m_host(host), m_port(port) { + } -const string defaultConnectionInfos::getHost() const -{ +const string defaultConnectionInfos::getHost() const { + return m_host; } -port_t defaultConnectionInfos::getPort() const -{ +port_t defaultConnectionInfos::getPort() const { + return m_port; } diff --git a/src/vmime/net/defaultConnectionInfos.hpp b/src/vmime/net/defaultConnectionInfos.hpp index 50673bbc..f3488595 100644 --- a/src/vmime/net/defaultConnectionInfos.hpp +++ b/src/vmime/net/defaultConnectionInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ namespace net { /** Information about the connection used by a service. */ -class VMIME_EXPORT defaultConnectionInfos : public connectionInfos -{ +class VMIME_EXPORT defaultConnectionInfos : public connectionInfos { + public: defaultConnectionInfos(const string& host, const port_t port); diff --git a/src/vmime/net/defaultTimeoutHandler.cpp b/src/vmime/net/defaultTimeoutHandler.cpp index 306289c0..f5dcc7d6 100644 --- a/src/vmime/net/defaultTimeoutHandler.cpp +++ b/src/vmime/net/defaultTimeoutHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,39 +34,39 @@ namespace vmime { namespace net { -defaultTimeoutHandler::defaultTimeoutHandler() -{ +defaultTimeoutHandler::defaultTimeoutHandler() { + m_startTime = time(NULL); } -defaultTimeoutHandler::~defaultTimeoutHandler() -{ +defaultTimeoutHandler::~defaultTimeoutHandler() { + } -bool defaultTimeoutHandler::isTimeOut() -{ +bool defaultTimeoutHandler::isTimeOut() { + return time(NULL) - m_startTime >= 30; } -void defaultTimeoutHandler::resetTimeOut() -{ +void defaultTimeoutHandler::resetTimeOut() { + m_startTime = time(NULL); } -bool defaultTimeoutHandler::handleTimeOut() -{ +bool defaultTimeoutHandler::handleTimeOut() { + return false; } -shared_ptr defaultTimeoutHandlerFactory::create() -{ +shared_ptr defaultTimeoutHandlerFactory::create() { + return make_shared (); } diff --git a/src/vmime/net/defaultTimeoutHandler.hpp b/src/vmime/net/defaultTimeoutHandler.hpp index a45b9739..545c6550 100644 --- a/src/vmime/net/defaultTimeoutHandler.hpp +++ b/src/vmime/net/defaultTimeoutHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,9 +44,8 @@ namespace net { * is to throw a exceptions::operation_timed_out exception when an * operation is blocked for more than 30 seconds. */ +class VMIME_EXPORT defaultTimeoutHandler : public timeoutHandler { -class VMIME_EXPORT defaultTimeoutHandler : public timeoutHandler -{ public: defaultTimeoutHandler(); @@ -64,9 +63,8 @@ private: /** A class that creates default timeout handlers. */ +class defaultTimeoutHandlerFactory : public timeoutHandlerFactory { -class defaultTimeoutHandlerFactory : public timeoutHandlerFactory -{ public: shared_ptr create(); diff --git a/src/vmime/net/events.cpp b/src/vmime/net/events.cpp index 6d056ae6..86608127 100644 --- a/src/vmime/net/events.cpp +++ b/src/vmime/net/events.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,13 +42,13 @@ namespace events { // event // -event::event() -{ +event::event() { + } -event::~event() -{ +event::~event() { + } @@ -59,10 +59,14 @@ event::~event() const char* messageCountEvent::EVENT_CLASS = "messageCountEvent"; -messageCountEvent::messageCountEvent - (const shared_ptr & folder, const Types type, const std::vector & nums) - : m_folder(folder), m_type(type) -{ +messageCountEvent::messageCountEvent( + const shared_ptr & folder, + const Types type, + const std::vector & nums +) + : m_folder(folder), + m_type(type) { + m_nums.resize(nums.size()); std::copy(nums.begin(), nums.end(), m_nums.begin()); } @@ -73,17 +77,18 @@ messageCountEvent::Types messageCountEvent::getType() const { return (m_type); } const std::vector & messageCountEvent::getNumbers() const { return (m_nums); } -void messageCountEvent::dispatch(messageCountListener* listener) -{ - if (m_type == TYPE_ADDED) +void messageCountEvent::dispatch(messageCountListener* listener) { + + if (m_type == TYPE_ADDED) { listener->messagesAdded(dynamicCast (shared_from_this())); - else + } else { listener->messagesRemoved(dynamicCast (shared_from_this())); + } } -const char* messageCountEvent::getClass() const -{ +const char* messageCountEvent::getClass() const { + return EVENT_CLASS; } @@ -95,10 +100,14 @@ const char* messageCountEvent::getClass() const const char* messageChangedEvent::EVENT_CLASS = "messageChangedEvent"; -messageChangedEvent::messageChangedEvent - (const shared_ptr & folder, const Types type, const std::vector & nums) - : m_folder(folder), m_type(type) -{ +messageChangedEvent::messageChangedEvent( + const shared_ptr & folder, + const Types type, + const std::vector & nums +) + : m_folder(folder), + m_type(type) { + m_nums.resize(nums.size()); std::copy(nums.begin(), nums.end(), m_nums.begin()); } @@ -109,14 +118,14 @@ messageChangedEvent::Types messageChangedEvent::getType() const { return (m_type const std::vector & messageChangedEvent::getNumbers() const { return (m_nums); } -void messageChangedEvent::dispatch(messageChangedListener* listener) -{ +void messageChangedEvent::dispatch(messageChangedListener* listener) { + listener->messageChanged(dynamicCast (shared_from_this())); } -const char* messageChangedEvent::getClass() const -{ +const char* messageChangedEvent::getClass() const { + return EVENT_CLASS; } @@ -128,11 +137,17 @@ const char* messageChangedEvent::getClass() const const char* folderEvent::EVENT_CLASS = "folderEvent"; -folderEvent::folderEvent - (const shared_ptr & folder, const Types type, - const utility::path& oldPath, const utility::path& newPath) - : m_folder(folder), m_type(type), m_oldPath(oldPath), m_newPath(newPath) -{ +folderEvent::folderEvent( + const shared_ptr & folder, + const Types type, + const utility::path& oldPath, + const utility::path& newPath +) + : m_folder(folder), + m_type(type), + m_oldPath(oldPath), + m_newPath(newPath) { + } @@ -140,19 +155,18 @@ shared_ptr folderEvent::getFolder() const { return (m_folder); } folderEvent::Types folderEvent::getType() const { return (m_type); } -void folderEvent::dispatch(folderListener* listener) -{ - switch (m_type) - { - case TYPE_CREATED: listener->folderCreated(dynamicCast (shared_from_this())); break; - case TYPE_RENAMED: listener->folderRenamed(dynamicCast (shared_from_this())); break; - case TYPE_DELETED: listener->folderDeleted(dynamicCast (shared_from_this())); break; +void folderEvent::dispatch(folderListener* listener) { + + switch (m_type) { + case TYPE_CREATED: listener->folderCreated(dynamicCast (shared_from_this())); break; + case TYPE_RENAMED: listener->folderRenamed(dynamicCast (shared_from_this())); break; + case TYPE_DELETED: listener->folderDeleted(dynamicCast (shared_from_this())); break; } } -const char* folderEvent::getClass() const -{ +const char* folderEvent::getClass() const { + return EVENT_CLASS; } diff --git a/src/vmime/net/events.hpp b/src/vmime/net/events.hpp index 772c4d9d..2ad64e79 100644 --- a/src/vmime/net/events.hpp +++ b/src/vmime/net/events.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,9 +46,8 @@ namespace events { /** Event occurring on folders or messages. */ +class VMIME_EXPORT event : public object, public enable_shared_from_this { -class VMIME_EXPORT event : public object, public enable_shared_from_this -{ public: event(); @@ -60,22 +59,24 @@ public: /** Event about the message count in a folder. */ +class VMIME_EXPORT messageCountEvent : public event { -class VMIME_EXPORT messageCountEvent : public event -{ public: static const char* EVENT_CLASS; - enum Types - { + enum Types { TYPE_ADDED, /**< New messages have been added. */ TYPE_REMOVED /**< Messages have been expunged (renumbering). */ }; - messageCountEvent(const shared_ptr & folder, const Types type, const std::vector & nums); + messageCountEvent( + const shared_ptr & folder, + const Types type, + const std::vector & nums + ); /** Return the folder in which messages have been added/removed. * @@ -114,9 +115,8 @@ private: /** Listener for events about the message count in a folder. */ +class VMIME_EXPORT messageCountListener { -class VMIME_EXPORT messageCountListener -{ protected: virtual ~messageCountListener() { } @@ -130,21 +130,23 @@ public: /** Event occuring on a message. */ +class VMIME_EXPORT messageChangedEvent : public event { -class VMIME_EXPORT messageChangedEvent : public event -{ public: static const char* EVENT_CLASS; - enum Types - { + enum Types { TYPE_FLAGS // flags changed }; - messageChangedEvent(const shared_ptr & folder, const Types type, const std::vector & nums); + messageChangedEvent( + const shared_ptr & folder, + const Types type, + const std::vector & nums + ); /** Return the folder in which messages have changed. * @@ -183,9 +185,8 @@ private: /** Listener for events occuring on a message. */ +class VMIME_EXPORT messageChangedListener { -class VMIME_EXPORT messageChangedListener -{ protected: virtual ~messageChangedListener() { } @@ -198,23 +199,26 @@ public: /** Event occuring on a folder. */ +class VMIME_EXPORT folderEvent : public event { -class VMIME_EXPORT folderEvent : public event -{ public: static const char* EVENT_CLASS; - enum Types - { + enum Types { TYPE_CREATED, /**< A folder was created. */ TYPE_DELETED, /**< A folder was deleted. */ TYPE_RENAMED /**< A folder was renamed. */ }; - folderEvent(const shared_ptr & folder, const Types type, const utility::path& oldPath, const utility::path& newPath); + folderEvent( + const shared_ptr & folder, + const Types type, + const utility::path& oldPath, + const utility::path& newPath + ); /** Return the folder on which the event occurred. * @@ -248,9 +252,8 @@ private: /** Listener for events occuring on a folder. */ +class VMIME_EXPORT folderListener { -class VMIME_EXPORT folderListener -{ protected: virtual ~folderListener() { } diff --git a/src/vmime/net/fetchAttributes.cpp b/src/vmime/net/fetchAttributes.cpp index d499674c..d9b54b83 100644 --- a/src/vmime/net/fetchAttributes.cpp +++ b/src/vmime/net/fetchAttributes.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,51 +39,54 @@ namespace net { fetchAttributes::fetchAttributes() - : m_predefinedAttribs(0) -{ + : m_predefinedAttribs(0) { + } fetchAttributes::fetchAttributes(const int attribs) - : m_predefinedAttribs(attribs) -{ + : m_predefinedAttribs(attribs) { + } fetchAttributes::fetchAttributes(const fetchAttributes& attribs) - : object() -{ + : object() { + m_predefinedAttribs = attribs.m_predefinedAttribs; m_headers = attribs.m_headers; } -void fetchAttributes::add(const int attribs) -{ +void fetchAttributes::add(const int attribs) { + m_predefinedAttribs |= attribs; } -void fetchAttributes::add(const string& header) -{ +void fetchAttributes::add(const string& header) { + m_headers.push_back(utility::stringUtils::toLower(header)); } -bool fetchAttributes::has(const int attribs) const -{ +bool fetchAttributes::has(const int attribs) const { + return (m_predefinedAttribs & attribs) != 0; } -bool fetchAttributes::has(const string& header) const -{ - return std::find(m_headers.begin(), m_headers.end(), utility::stringUtils::toLower(header)) != m_headers.end(); +bool fetchAttributes::has(const string& header) const { + + return std::find( + m_headers.begin(), m_headers.end(), + utility::stringUtils::toLower(header) + ) != m_headers.end(); } -const std::vector fetchAttributes::getHeaderFields() const -{ +const std::vector fetchAttributes::getHeaderFields() const { + return m_headers; } diff --git a/src/vmime/net/fetchAttributes.hpp b/src/vmime/net/fetchAttributes.hpp index d01e9f50..19d92627 100644 --- a/src/vmime/net/fetchAttributes.hpp +++ b/src/vmime/net/fetchAttributes.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,14 +42,13 @@ namespace net { /** Holds a set of attributes to fetch for a message. */ -class VMIME_EXPORT fetchAttributes : public object -{ +class VMIME_EXPORT fetchAttributes : public object { + public: /** Predefined attributes that can be fetched. */ - enum PredefinedFetchAttributes - { + enum PredefinedFetchAttributes { ENVELOPE = (1 << 0), /**< Sender, recipients, date, subject. */ STRUCTURE = (1 << 1), /**< MIME structure (body parts). */ CONTENT_INFO = (1 << 2), /**< Top-level content type. */ @@ -114,8 +113,7 @@ public: * @param attribs one or more OR-ed values of the PredefinedFetchAttributes enum * @return true if the specified attributes are to be fetched */ - VMIME_DEPRECATED inline bool operator&(const int attribs) const - { + VMIME_DEPRECATED inline bool operator&(const int attribs) const { return has(attribs); } diff --git a/src/vmime/net/folder.cpp b/src/vmime/net/folder.cpp index 38f60523..6e01b602 100644 --- a/src/vmime/net/folder.cpp +++ b/src/vmime/net/folder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,96 +36,91 @@ namespace vmime { namespace net { -int folder::getType() -{ +int folder::getType() { + return getAttributes().getType(); } -int folder::getFlags() -{ +int folder::getFlags() { + return getAttributes().getFlags(); } -void folder::addMessageChangedListener(events::messageChangedListener* l) -{ +void folder::addMessageChangedListener(events::messageChangedListener* l) { + m_messageChangedListeners.push_back(l); } -void folder::removeMessageChangedListener(events::messageChangedListener* l) -{ +void folder::removeMessageChangedListener(events::messageChangedListener* l) { + std::remove(m_messageChangedListeners.begin(), m_messageChangedListeners.end(), l); } -void folder::notifyMessageChanged(const shared_ptr & event) -{ +void folder::notifyMessageChanged(const shared_ptr & event) { + for (std::list ::iterator - it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it) - { + it = m_messageChangedListeners.begin() ; it != m_messageChangedListeners.end() ; ++it) { + event->dispatch(*it); } } -void folder::addMessageCountListener(events::messageCountListener* l) -{ +void folder::addMessageCountListener(events::messageCountListener* l) { + m_messageCountListeners.push_back(l); } -void folder::removeMessageCountListener(events::messageCountListener* l) -{ +void folder::removeMessageCountListener(events::messageCountListener* l) { + std::remove(m_messageCountListeners.begin(), m_messageCountListeners.end(), l); } -void folder::notifyMessageCount(const shared_ptr & event) -{ +void folder::notifyMessageCount(const shared_ptr & event) { + for (std::list ::iterator - it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it) - { + it = m_messageCountListeners.begin() ; it != m_messageCountListeners.end() ; ++it) { + event->dispatch(*it); } } -void folder::addFolderListener(events::folderListener* l) -{ +void folder::addFolderListener(events::folderListener* l) { + m_folderListeners.push_back(l); } -void folder::removeFolderListener(events::folderListener* l) -{ +void folder::removeFolderListener(events::folderListener* l) { + std::remove(m_folderListeners.begin(), m_folderListeners.end(), l); } -void folder::notifyFolder(const shared_ptr & event) -{ +void folder::notifyFolder(const shared_ptr & event) { + for (std::list ::iterator - it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it) - { + it = m_folderListeners.begin() ; it != m_folderListeners.end() ; ++it) { + event->dispatch(*it); } } -void folder::notifyEvent(const shared_ptr & event) -{ - if (event->getClass() == events::messageCountEvent::EVENT_CLASS) - { +void folder::notifyEvent(const shared_ptr & event) { + + if (event->getClass() == events::messageCountEvent::EVENT_CLASS) { notifyMessageCount(dynamicCast (event)); - } - else if (event->getClass() == events::messageChangedEvent::EVENT_CLASS) - { + } else if (event->getClass() == events::messageChangedEvent::EVENT_CLASS) { notifyMessageChanged(dynamicCast (event)); - } - else if (event->getClass() == events::folderEvent::EVENT_CLASS) - { + } else if (event->getClass() == events::folderEvent::EVENT_CLASS) { notifyFolder(dynamicCast (event)); } } diff --git a/src/vmime/net/folder.hpp b/src/vmime/net/folder.hpp index 8117d7d1..4d5cf6ef 100644 --- a/src/vmime/net/folder.hpp +++ b/src/vmime/net/folder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -58,17 +58,15 @@ class store; /** Abstract representation of a folder in a message store. */ +class VMIME_EXPORT folder : public object, public enable_shared_from_this { -class VMIME_EXPORT folder : public object, public enable_shared_from_this -{ protected: folder(const folder&) : object(), enable_shared_from_this () { } folder() { } - enum PrivateConstants - { + enum PrivateConstants { TYPE_UNDEFINED = 9999, /**< Used internally to indicate type has not been initialized yet. */ FLAG_UNDEFINED = 9999 /**< Used internally to indicate flags have not @@ -86,8 +84,7 @@ public: /** Open mode. */ - enum Modes - { + enum Modes { MODE_READ_ONLY, /**< Read-only mode (no modification to folder or messages is possible). */ MODE_READ_WRITE /**< Full access mode (read and write). */ }; @@ -273,11 +270,12 @@ public: * support returning the number or UID of an added message) * @throw exceptions::net_exception if an error occurs */ - virtual messageSet addMessage - (const shared_ptr & msg, - const int flags = -1, - vmime::datetime* date = NULL, - utility::progressListener* progress = NULL) = 0; + virtual messageSet addMessage( + const shared_ptr & msg, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ) = 0; /** Add a message to this folder. * @@ -291,12 +289,13 @@ public: * support returning the number or UID of an added message) * @throw exceptions::net_exception if an error occurs */ - virtual messageSet addMessage - (utility::inputStream& is, - const size_t size, - const int flags = -1, - vmime::datetime* date = NULL, - utility::progressListener* progress = NULL) = 0; + virtual messageSet addMessage( + utility::inputStream& is, + const size_t size, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ) = 0; /** Copy messages from this folder to another folder. * @@ -307,8 +306,10 @@ public: * support returning the number or UID of a copied message) * @throw exceptions::net_exception if an error occurs */ - virtual messageSet copyMessages - (const folder::path& dest, const messageSet& msgs) = 0; + virtual messageSet copyMessages( + const folder::path& dest, + const messageSet& msgs + ) = 0; /** Request folder status without opening it. * @@ -358,7 +359,11 @@ public: * @param progress progress listener, or NULL if not used * @throw exceptions::net_exception if an error occurs */ - virtual void fetchMessages(std::vector >& msg, const fetchAttributes& attribs, utility::progressListener* progress = NULL) = 0; + virtual void fetchMessages( + std::vector >& msg, + const fetchAttributes& attribs, + utility::progressListener* progress = NULL + ) = 0; /** Fetch objects for the specified message. * @@ -366,7 +371,10 @@ public: * @param attribs set of attributes to fetch * @throw exceptions::net_exception if an error occurs */ - virtual void fetchMessage(const shared_ptr & msg, const fetchAttributes& attribs) = 0; + virtual void fetchMessage( + const shared_ptr & msg, + const fetchAttributes& attribs + ) = 0; /** Get new references to messages in this folder, given either their * sequence numbers or UIDs, and fetch objects for them at the same time. @@ -378,8 +386,10 @@ public: * @see folder::getMessages() * @see folder::fetchMessages() */ - virtual std::vector > getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs) = 0; + virtual std::vector > getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs + ) = 0; /** Return the list of fetchable objects supported by * the underlying protocol (see folder::fetchAttributes). diff --git a/src/vmime/net/folderAttributes.cpp b/src/vmime/net/folderAttributes.cpp index 1a283764..107007cf 100644 --- a/src/vmime/net/folderAttributes.cpp +++ b/src/vmime/net/folderAttributes.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,8 +39,8 @@ namespace net { folderAttributes::folderAttributes() : m_type(TYPE_CONTAINS_FOLDERS | TYPE_CONTAINS_MESSAGES), m_flags(0), - m_specialUse(SPECIALUSE_NONE) -{ + m_specialUse(SPECIALUSE_NONE) { + } @@ -49,67 +49,67 @@ folderAttributes::folderAttributes(const folderAttributes& attribs) m_type(attribs.m_type), m_flags(attribs.m_flags), m_userFlags(attribs.m_userFlags), - m_specialUse(attribs.m_specialUse) -{ + m_specialUse(attribs.m_specialUse) { + } -int folderAttributes::getType() const -{ +int folderAttributes::getType() const { + return m_type; } -void folderAttributes::setType(const int type) -{ +void folderAttributes::setType(const int type) { + m_type = type; } -int folderAttributes::getSpecialUse() const -{ +int folderAttributes::getSpecialUse() const { + return m_specialUse; } -void folderAttributes::setSpecialUse(const int use) -{ +void folderAttributes::setSpecialUse(const int use) { + m_specialUse = use; } -int folderAttributes::getFlags() const -{ +int folderAttributes::getFlags() const { + return m_flags; } -void folderAttributes::setFlags(const int flags) -{ +void folderAttributes::setFlags(const int flags) { + m_flags = flags; } -bool folderAttributes::hasFlag(const int flag) -{ +bool folderAttributes::hasFlag(const int flag) { + return (m_flags & flag) != 0; } -const std::vector folderAttributes::getUserFlags() const -{ +const std::vector folderAttributes::getUserFlags() const { + return m_userFlags; } -void folderAttributes::setUserFlags(const std::vector & flags) -{ +void folderAttributes::setUserFlags(const std::vector & flags) { + m_userFlags = flags; } -bool folderAttributes::hasUserFlag(const string& flag) -{ +bool folderAttributes::hasUserFlag(const string& flag) { + return std::find(m_userFlags.begin(), m_userFlags.end(), flag) != m_userFlags.end(); } diff --git a/src/vmime/net/folderAttributes.hpp b/src/vmime/net/folderAttributes.hpp index d6c51926..b91347b5 100644 --- a/src/vmime/net/folderAttributes.hpp +++ b/src/vmime/net/folderAttributes.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,22 +42,20 @@ namespace net { /** Holds a set of attributes for a folder. */ -class VMIME_EXPORT folderAttributes : public object -{ +class VMIME_EXPORT folderAttributes : public object { + public: /** Folder types. */ - enum Types - { + enum Types { TYPE_CONTAINS_FOLDERS = (1 << 0), /**< Folder can contain folders. */ TYPE_CONTAINS_MESSAGES = (1 << 1) /**< Folder can contain messages. */ }; /** Folder flags. */ - enum Flags - { + enum Flags { FLAG_HAS_CHILDREN = (1 << 0), /**< Folder contains subfolders. */ FLAG_NO_OPEN = (1 << 1) /**< Folder cannot be open. */ }; @@ -66,8 +64,7 @@ public: * Not all protocols support this. At the current time, only IMAP supports this, * if the server has the SPECIAL-USE capability. */ - enum SpecialUses - { + enum SpecialUses { SPECIALUSE_NONE, /**< User folder, no special use (or unknown). */ SPECIALUSE_ALL, /**< Virtual folder containing all messages. */ SPECIALUSE_ARCHIVE, /**< Folder is used to archives messages (server-dependent). */ @@ -139,7 +136,7 @@ public: * * @param flag combination of one ore more folder flags (see folderAttributes::Flags enum) * @return true if the specified flags are all set, or false otherwise - */ + */ bool hasFlag(const int flag); /** Set the user-defined flags of the folder. diff --git a/src/vmime/net/folderStatus.hpp b/src/vmime/net/folderStatus.hpp index e80b5a9f..fcc4afc0 100644 --- a/src/vmime/net/folderStatus.hpp +++ b/src/vmime/net/folderStatus.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,9 +40,8 @@ namespace net { /** Holds the status of a mail store folder. */ +class VMIME_EXPORT folderStatus : public object { -class VMIME_EXPORT folderStatus : public object -{ public: /** Returns the total number of messages in the folder. diff --git a/src/vmime/net/imap/IMAPCommand.cpp b/src/vmime/net/imap/IMAPCommand.cpp index 908b9152..8911ed02 100644 --- a/src/vmime/net/imap/IMAPCommand.cpp +++ b/src/vmime/net/imap/IMAPCommand.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,14 +41,15 @@ namespace imap { IMAPCommand::IMAPCommand(const string& text, const string& traceText) - : m_text(text), m_traceText(traceText) -{ + : m_text(text), + m_traceText(traceText) { + } // static -shared_ptr IMAPCommand::LOGIN(const string& username, const string& password) -{ +shared_ptr IMAPCommand::LOGIN(const string& username, const string& password) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "LOGIN " << IMAPUtils::quoteString(username) @@ -63,8 +64,8 @@ shared_ptr IMAPCommand::LOGIN(const string& username, const string // static -shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName) -{ +shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTHENTICATE " << mechName; @@ -74,8 +75,8 @@ shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName) // static -shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName, const string& initialResponse) -{ +shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName, const string& initialResponse) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTHENTICATE " << mechName << " " << initialResponse; @@ -85,8 +86,8 @@ shared_ptr IMAPCommand::AUTHENTICATE(const string& mechName, const // static -shared_ptr IMAPCommand::LIST(const string& refName, const string& mailboxName) -{ +shared_ptr IMAPCommand::LIST(const string& refName, const string& mailboxName) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "LIST " << IMAPUtils::quoteString(refName) @@ -97,25 +98,28 @@ shared_ptr IMAPCommand::LIST(const string& refName, const string& // static -shared_ptr IMAPCommand::SELECT - (const bool readOnly, const string& mailboxName, const std::vector & params) -{ +shared_ptr IMAPCommand::SELECT( + const bool readOnly, + const string& mailboxName, + const std::vector & params +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); - if (readOnly) + if (readOnly) { cmd << "EXAMINE "; - else + } else { cmd << "SELECT "; + } cmd << IMAPUtils::quoteString(mailboxName); - if (!params.empty()) - { + if (!params.empty()) { + cmd << " ("; - for (size_t i = 0, n = params.size() ; i < n ; ++i) - { + for (size_t i = 0, n = params.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << params[i]; } @@ -128,17 +132,18 @@ shared_ptr IMAPCommand::SELECT // static -shared_ptr IMAPCommand::STATUS - (const string& mailboxName, const std::vector & attribs) -{ +shared_ptr IMAPCommand::STATUS( + const string& mailboxName, + const std::vector & attribs +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "STATUS " << IMAPUtils::quoteString(mailboxName); cmd << " ("; - for (size_t i = 0, n = attribs.size() ; i < n ; ++i) - { + for (size_t i = 0, n = attribs.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << attribs[i]; } @@ -150,19 +155,20 @@ shared_ptr IMAPCommand::STATUS // static -shared_ptr IMAPCommand::CREATE - (const string& mailboxName, const std::vector & params) -{ +shared_ptr IMAPCommand::CREATE( + const string& mailboxName, + const std::vector & params +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "CREATE " << IMAPUtils::quoteString(mailboxName); - if (!params.empty()) - { + if (!params.empty()) { + cmd << " ("; - for (size_t i = 0, n = params.size() ; i < n ; ++i) - { + for (size_t i = 0, n = params.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << params[i]; } @@ -175,8 +181,8 @@ shared_ptr IMAPCommand::CREATE // static -shared_ptr IMAPCommand::DELETE(const string& mailboxName) -{ +shared_ptr IMAPCommand::DELETE(const string& mailboxName) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "DELETE " << IMAPUtils::quoteString(mailboxName); @@ -186,9 +192,11 @@ shared_ptr IMAPCommand::DELETE(const string& mailboxName) // static -shared_ptr IMAPCommand::RENAME - (const string& mailboxName, const string& newMailboxName) -{ +shared_ptr IMAPCommand::RENAME( + const string& mailboxName, + const string& newMailboxName +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "RENAME " << IMAPUtils::quoteString(mailboxName) @@ -199,27 +207,29 @@ shared_ptr IMAPCommand::RENAME // static -shared_ptr IMAPCommand::FETCH - (const messageSet& msgs, const std::vector & params) -{ +shared_ptr IMAPCommand::FETCH( + const messageSet& msgs, + const std::vector & params +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); - if (msgs.isUIDSet()) + if (msgs.isUIDSet()) { cmd << "UID FETCH " << IMAPUtils::messageSetToSequenceSet(msgs); - else + } else { cmd << "FETCH " << IMAPUtils::messageSetToSequenceSet(msgs); - - if (params.size() == 1) - { - cmd << " " << params[0]; } - else - { + + if (params.size() == 1) { + + cmd << " " << params[0]; + + } else { + cmd << " ("; - for (size_t i = 0, n = params.size() ; i < n ; ++i) - { + for (size_t i = 0, n = params.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << params[i]; } @@ -232,28 +242,32 @@ shared_ptr IMAPCommand::FETCH // static -shared_ptr IMAPCommand::STORE - (const messageSet& msgs, const int mode, const std::vector & flags) -{ +shared_ptr IMAPCommand::STORE( + const messageSet& msgs, + const int mode, + const std::vector & flags +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); - if (msgs.isUIDSet()) + if (msgs.isUIDSet()) { cmd << "UID STORE " << IMAPUtils::messageSetToSequenceSet(msgs); - else + } else { cmd << "STORE " << IMAPUtils::messageSetToSequenceSet(msgs); + } - if (mode == message::FLAG_MODE_ADD) + if (mode == message::FLAG_MODE_ADD) { cmd << " +FLAGS "; - else if (mode == message::FLAG_MODE_REMOVE) + } else if (mode == message::FLAG_MODE_REMOVE) { cmd << " -FLAGS "; - else // if (mode == message::FLAG_MODE_SET) + } else { // if (mode == message::FLAG_MODE_SET) cmd << " FLAGS "; + } cmd << "("; - for (size_t i = 0, n = flags.size() ; i < n ; ++i) - { + for (size_t i = 0, n = flags.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << flags[i]; } @@ -265,20 +279,22 @@ shared_ptr IMAPCommand::STORE // static -shared_ptr IMAPCommand::APPEND - (const string& mailboxName, const std::vector & flags, - vmime::datetime* date, const size_t size) -{ +shared_ptr IMAPCommand::APPEND( + const string& mailboxName, + const std::vector & flags, + vmime::datetime* date, + const size_t size +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "APPEND " << IMAPUtils::quoteString(mailboxName); - if (!flags.empty()) - { + if (!flags.empty()) { + cmd << " ("; - for (size_t i = 0, n = flags.size() ; i < n ; ++i) - { + for (size_t i = 0, n = flags.size() ; i < n ; ++i) { if (i != 0) cmd << " "; cmd << flags[i]; } @@ -286,8 +302,9 @@ shared_ptr IMAPCommand::APPEND cmd << ")"; } - if (date != NULL) + if (date != NULL) { cmd << " " << IMAPUtils::dateTime(*date); + } cmd << " {" << size << "}"; @@ -296,16 +313,19 @@ shared_ptr IMAPCommand::APPEND // static -shared_ptr IMAPCommand::COPY - (const messageSet& msgs, const string& mailboxName) -{ +shared_ptr IMAPCommand::COPY( + const messageSet& msgs, + const string& mailboxName +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); - if (msgs.isUIDSet()) + if (msgs.isUIDSet()) { cmd << "UID COPY " << IMAPUtils::messageSetToSequenceSet(msgs); - else + } else { cmd << "COPY " << IMAPUtils::messageSetToSequenceSet(msgs); + } cmd << " " << IMAPUtils::quoteString(mailboxName); @@ -314,90 +334,97 @@ shared_ptr IMAPCommand::COPY // static -shared_ptr IMAPCommand::SEARCH - (const std::vector & keys, const vmime::charset* charset) -{ +shared_ptr IMAPCommand::SEARCH( + const std::vector & keys, + const vmime::charset* charset +) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "SEARCH"; - if (charset) + if (charset) { cmd << " CHARSET " << charset->getName(); + } - for (size_t i = 0, n = keys.size() ; i < n ; ++i) + for (size_t i = 0, n = keys.size() ; i < n ; ++i) { cmd << " " << keys[i]; + } return createCommand(cmd.str()); } // static -shared_ptr IMAPCommand::STARTTLS() -{ +shared_ptr IMAPCommand::STARTTLS() { + return createCommand("STARTTLS"); } // static -shared_ptr IMAPCommand::CAPABILITY() -{ +shared_ptr IMAPCommand::CAPABILITY() { + return createCommand("CAPABILITY"); } // static -shared_ptr IMAPCommand::NOOP() -{ +shared_ptr IMAPCommand::NOOP() { + return createCommand("NOOP"); } // static -shared_ptr IMAPCommand::EXPUNGE() -{ +shared_ptr IMAPCommand::EXPUNGE() { + return createCommand("EXPUNGE"); } // static -shared_ptr IMAPCommand::CLOSE() -{ +shared_ptr IMAPCommand::CLOSE() { + return createCommand("CLOSE"); } // static -shared_ptr IMAPCommand::LOGOUT() -{ +shared_ptr IMAPCommand::LOGOUT() { + return createCommand("LOGOUT"); } // static -shared_ptr IMAPCommand::createCommand - (const string& text, const string& traceText) -{ - if (traceText.empty()) +shared_ptr IMAPCommand::createCommand( + const string& text, + const string& traceText +) { + + if (traceText.empty()) { return shared_ptr (new IMAPCommand(text, text)); - else + } else { return shared_ptr (new IMAPCommand(text, traceText)); + } } -const string IMAPCommand::getText() const -{ +const string IMAPCommand::getText() const { + return m_text; } -const string IMAPCommand::getTraceText() const -{ +const string IMAPCommand::getTraceText() const { + return m_traceText; } -void IMAPCommand::send(const shared_ptr & conn) -{ +void IMAPCommand::send(const shared_ptr & conn) { + conn->sendCommand(dynamicCast (shared_from_this())); } diff --git a/src/vmime/net/imap/IMAPCommand.hpp b/src/vmime/net/imap/IMAPCommand.hpp index 09f34c66..4915a577 100644 --- a/src/vmime/net/imap/IMAPCommand.hpp +++ b/src/vmime/net/imap/IMAPCommand.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -48,8 +48,8 @@ class IMAPConnection; /** An IMAP command that will be sent to the server. */ -class VMIME_EXPORT IMAPCommand : public object, public enable_shared_from_this -{ +class VMIME_EXPORT IMAPCommand : public object, public enable_shared_from_this { + public: static shared_ptr LOGIN(const string& username, const string& password); diff --git a/src/vmime/net/imap/IMAPConnection.cpp b/src/vmime/net/imap/IMAPConnection.cpp index 7fc86188..0e593829 100644 --- a/src/vmime/net/imap/IMAPConnection.cpp +++ b/src/vmime/net/imap/IMAPConnection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -66,17 +66,30 @@ namespace net { namespace imap { -IMAPConnection::IMAPConnection(const shared_ptr & store, const shared_ptr & auth) - : m_store(store), m_auth(auth), m_socket(null), m_parser(null), m_tag(null), - m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(null), - m_secured(false), m_firstTag(true), m_capabilitiesFetched(false), m_noModSeq(false) -{ +IMAPConnection::IMAPConnection( + const shared_ptr & store, + const shared_ptr & auth +) + : m_store(store), + m_auth(auth), + m_socket(null), + m_parser(null), + m_tag(null), + m_hierarchySeparator('\0'), + m_state(STATE_NONE), + m_timeoutHandler(null), + m_secured(false), + m_firstTag(true), + m_capabilitiesFetched(false), + m_noModSeq(false) { + static int connectionId = 0; m_tag = make_shared (); - if (store->getTracerFactory()) + if (store->getTracerFactory()) { m_tracer = store->getTracerFactory()->create(store, ++connectionId); + } m_parser = make_shared (); m_parser->setTag(m_tag); @@ -84,26 +97,28 @@ IMAPConnection::IMAPConnection(const shared_ptr & store, const shared } -IMAPConnection::~IMAPConnection() -{ - try - { - if (isConnected()) +IMAPConnection::~IMAPConnection() { + + try { + + if (isConnected()) { disconnect(); - else if (m_socket) + } else if (m_socket) { internalDisconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void IMAPConnection::connect() -{ - if (isConnected()) +void IMAPConnection::connect() { + + if (isConnected()) { throw exceptions::already_connected(); + } m_state = STATE_NONE; m_hierarchySeparator = '\0'; @@ -114,16 +129,17 @@ void IMAPConnection::connect() shared_ptr store = m_store.lock(); // Create the time-out handler - if (store->getTimeoutHandlerFactory()) + if (store->getTimeoutHandlerFactory()) { m_timeoutHandler = store->getTimeoutHandlerFactory()->create(); + } // Create and connect the socket m_socket = store->getSocketFactory()->create(m_timeoutHandler); m_socket->setTracer(m_tracer); #if VMIME_HAVE_TLS_SUPPORT - if (store->isIMAPS()) // dedicated port/IMAPS - { + if (store->isIMAPS()) { // dedicated port/IMAPS + shared_ptr tlsSession = tls::TLSSession::create (store->getCertificateVerifier(), store->getSession()->getTLSProperties()); @@ -135,8 +151,8 @@ void IMAPConnection::connect() m_secured = true; m_cntInfos = make_shared (address, port, tlsSession, tlsSocket); - } - else + + } else #endif // VMIME_HAVE_TLS_SUPPORT { m_cntInfos = make_shared (address, port); @@ -160,19 +176,19 @@ void IMAPConnection::connect() scoped_ptr greet(m_parser->readGreeting()); bool needAuth = false; - if (greet->resp_cond_bye()) - { + if (greet->resp_cond_bye()) { + internalDisconnect(); throw exceptions::connection_greeting_error(greet->getErrorLog()); - } - else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH) - { + + } else if (greet->resp_cond_auth()->condition() != IMAPParser::resp_cond_auth::PREAUTH) { + needAuth = true; } if (greet->resp_cond_auth()->resp_text()->resp_text_code() && - greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data()) - { + greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data()) { + processCapabilityResponseData(greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data()); } @@ -183,28 +199,25 @@ void IMAPConnection::connect() const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED) && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED); - if (!store->isIMAPS() && tls) // only if not IMAPS - { - try - { + if (!store->isIMAPS() && tls) { // only if not IMAPS + + try { + startTLS(); - } + // Non-fatal error - catch (exceptions::command_error&) - { - if (tlsRequired) - { + } catch (exceptions::command_error&) { + + if (tlsRequired) { m_state = STATE_NONE; throw; - } - else - { + } else { // TLS is not required, so don't bother } - } + // Fatal error - catch (...) - { + } catch (...) { + m_state = STATE_NONE; throw; } @@ -212,14 +225,14 @@ void IMAPConnection::connect() #endif // VMIME_HAVE_TLS_SUPPORT // Authentication - if (needAuth) - { - try - { + if (needAuth) { + + try { + authenticate(); - } - catch (...) - { + + } catch (...) { + m_state = STATE_NONE; throw; } @@ -233,34 +246,34 @@ void IMAPConnection::connect() } -void IMAPConnection::authenticate() -{ +void IMAPConnection::authenticate() { + getAuthenticator()->setService(m_store.lock()); #if VMIME_HAVE_SASL_SUPPORT // First, try SASL authentication - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) - { - try - { + if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) { + + try { + authenticateSASL(); return; - } - catch (exceptions::authentication_error&) - { - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK)) - { + + } catch (exceptions::authentication_error&) { + + if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK)) { + // Can't fallback on normal authentication internalDisconnect(); throw; - } - else - { + + } else { + // Ignore, will try normal authentication } - } - catch (exception&) - { + + } catch (exception&) { + internalDisconnect(); throw; } @@ -276,36 +289,38 @@ void IMAPConnection::authenticate() scoped_ptr resp(m_parser->readResponse()); - if (resp->isBad()) - { + if (resp->isBad()) { + internalDisconnect(); throw exceptions::command_error("LOGIN", resp->getErrorLog()); - } - else if (resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + + } else if (resp->response_done()->response_tagged()-> + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + internalDisconnect(); throw exceptions::authentication_error(resp->getErrorLog()); } // Server capabilities may change when logged in - if (!processCapabilityResponseData(resp.get())) + if (!processCapabilityResponseData(resp.get())) { invalidateCapabilities(); + } } #if VMIME_HAVE_SASL_SUPPORT -void IMAPConnection::authenticateSASL() -{ - if (!dynamicCast (getAuthenticator())) +void IMAPConnection::authenticateSASL() { + + if (!dynamicCast (getAuthenticator())) { throw exceptions::authentication_error("No SASL authenticator available."); + } const std::vector capa = getCapabilities(); std::vector saslMechs; - for (unsigned int i = 0 ; i < capa.size() ; ++i) - { + for (unsigned int i = 0 ; i < capa.size() ; ++i) { + const string& x = capa[i]; if (x.length() > 5 && @@ -313,53 +328,53 @@ void IMAPConnection::authenticateSASL() (x[1] == 'U' || x[1] == 'u') && (x[2] == 'T' || x[2] == 't') && (x[3] == 'H' || x[3] == 'h') && - x[4] == '=') - { + x[4] == '=') { + saslMechs.push_back(string(x.begin() + 5, x.end())); } } - if (saslMechs.empty()) + if (saslMechs.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } std::vector > mechList; shared_ptr saslContext = security::sasl::SASLContext::create(); - for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) - { - try - { - mechList.push_back - (saslContext->createMechanism(saslMechs[i])); - } - catch (exceptions::no_such_mechanism&) - { + for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) { + + try { + mechList.push_back(saslContext->createMechanism(saslMechs[i])); + } catch (exceptions::no_such_mechanism&) { // Ignore mechanism } } - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try to suggest a mechanism among all those supported shared_ptr suggestedMech = saslContext->suggestMechanism(mechList); - if (!suggestedMech) + if (!suggestedMech) { throw exceptions::authentication_error("Unable to suggest SASL mechanism."); + } // Allow application to choose which mechanisms to use mechList = dynamicCast (getAuthenticator())-> getAcceptableMechanisms(mechList, suggestedMech); - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try each mechanism in the list in turn - for (unsigned int i = 0 ; i < mechList.size() ; ++i) - { + for (unsigned int i = 0 ; i < mechList.size() ; ++i) { + shared_ptr mech = mechList[i]; shared_ptr saslSession = @@ -369,8 +384,8 @@ void IMAPConnection::authenticateSASL() shared_ptr authCmd; - if (saslSession->getMechanism()->hasInitialResponse()) - { + if (saslSession->getMechanism()->hasInitialResponse()) { + byte_t* initialResp = 0; size_t initialRespLen = 0; @@ -379,50 +394,50 @@ void IMAPConnection::authenticateSASL() string encodedInitialResp(saslContext->encodeB64(initialResp, initialRespLen)); delete [] initialResp; - if (encodedInitialResp.empty()) + if (encodedInitialResp.empty()) { authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), "="); - else + } else { authCmd = IMAPCommand::AUTHENTICATE(mech->getName(), encodedInitialResp); - } - else - { + } + + } else { + authCmd = IMAPCommand::AUTHENTICATE(mech->getName()); } authCmd->send(dynamicCast (shared_from_this())); - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + scoped_ptr resp(m_parser->readResponse()); if (resp->response_done() && resp->response_done()->response_tagged() && resp->response_done()->response_tagged()->resp_cond_state()-> - status() == IMAPParser::resp_cond_state::OK) - { + status() == IMAPParser::resp_cond_state::OK) { + m_socket = saslSession->getSecuredSocket(m_socket); return; - } - else - { + + } else { + std::vector respDataList = resp->continue_req_or_response_data(); string response; bool hasResponse = false; - for (unsigned int i = 0 ; i < respDataList.size() ; ++i) - { - if (respDataList[i]->continue_req()) - { + for (unsigned int i = 0 ; i < respDataList.size() ; ++i) { + + if (respDataList[i]->continue_req()) { + response = respDataList[i]->continue_req()->resp_text()->text(); hasResponse = true; break; } } - if (!hasResponse) - { + if (!hasResponse) { cont = false; continue; } @@ -433,8 +448,8 @@ void IMAPConnection::authenticateSASL() byte_t* resp = 0; size_t respLen = 0; - try - { + try { + // Extract challenge saslContext->decodeB64(response, &challenge, &challengeLen); @@ -446,22 +461,21 @@ void IMAPConnection::authenticateSASL() const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); - if (m_tracer) + if (m_tracer) { m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); + } // Server capabilities may change when logged in invalidateCapabilities(); - } - catch (exceptions::sasl_exception& e) - { - if (challenge) - { + + } catch (exceptions::sasl_exception& e) { + + if (challenge) { delete [] challenge; challenge = NULL; } - if (resp) - { + if (resp) { delete [] resp; resp = NULL; } @@ -469,31 +483,35 @@ void IMAPConnection::authenticateSASL() // Cancel SASL exchange sendRaw(utility::stringUtils::bytesFromString("*\r\n"), 3); - if (m_tracer) + if (m_tracer) { m_tracer->traceSend("*"); - } - catch (...) - { - if (challenge) - delete [] challenge; + } - if (resp) + } catch (...) { + + if (challenge) { + delete [] challenge; + } + + if (resp) { delete [] resp; + } throw; } - if (challenge) + if (challenge) { delete [] challenge; + } - if (resp) + if (resp) { delete [] resp; + } } } } - throw exceptions::authentication_error - ("Could not authenticate using SASL: all mechanisms failed."); + throw exceptions::authentication_error("Could not authenticate using SASL: all mechanisms failed."); } #endif // VMIME_HAVE_SASL_SUPPORT @@ -501,27 +519,26 @@ void IMAPConnection::authenticateSASL() #if VMIME_HAVE_TLS_SUPPORT -void IMAPConnection::startTLS() -{ - try - { +void IMAPConnection::startTLS() { + + try { + IMAPCommand::STARTTLS()->send(dynamicCast (shared_from_this())); scoped_ptr resp(m_parser->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error - ("STARTTLS", resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("STARTTLS", resp->getErrorLog(), "bad response"); } - shared_ptr tlsSession = tls::TLSSession::create - (m_store.lock()->getCertificateVerifier(), - m_store.lock()->getSession()->getTLSProperties()); + shared_ptr tlsSession = tls::TLSSession::create( + m_store.lock()->getCertificateVerifier(), + m_store.lock()->getSession()->getTLSProperties() + ); - shared_ptr tlsSocket = - tlsSession->getSocket(m_socket); + shared_ptr tlsSocket = tlsSession->getSocket(m_socket); tlsSocket->handshake(); @@ -529,8 +546,9 @@ void IMAPConnection::startTLS() m_parser->setSocket(m_socket); m_secured = true; - m_cntInfos = make_shared - (m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket); + m_cntInfos = make_shared ( + m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket + ); // " Once TLS has been started, the client MUST discard cached // information about server capabilities and SHOULD re-issue the @@ -538,14 +556,14 @@ void IMAPConnection::startTLS() // man-in-the-middle attacks which alter the capabilities list prior // to STARTTLS. " (RFC-2595) invalidateCapabilities(); - } - catch (exceptions::command_error&) - { + + } catch (exceptions::command_error&) { + // Non-fatal error throw; - } - catch (exception&) - { + + } catch (exception&) { + // Fatal error internalDisconnect(); throw; @@ -555,24 +573,41 @@ void IMAPConnection::startTLS() #endif // VMIME_HAVE_TLS_SUPPORT -const std::vector IMAPConnection::getCapabilities() -{ - if (!m_capabilitiesFetched) +const std::vector IMAPConnection::getCapabilities() { + + if (!m_capabilitiesFetched) { fetchCapabilities(); + } return m_capabilities; } -bool IMAPConnection::hasCapability(const string& capa) -{ - if (!m_capabilitiesFetched) +bool IMAPConnection::hasCapability(const string& capa) { + + if (!m_capabilitiesFetched) { fetchCapabilities(); + } const string normCapa = utility::stringUtils::toUpper(capa); - for (size_t i = 0, n = m_capabilities.size() ; i < n ; ++i) - { + for (size_t i = 0, n = m_capabilities.size() ; i < n ; ++i) { + + if (m_capabilities[i] == normCapa) { + return true; + } + } + + return false; +} + + +bool IMAPConnection::hasCapability(const string& capa) const { + + const string normCapa = utility::stringUtils::toUpper(capa); + + for (size_t i = 0, n = m_capabilities.size() ; i < n ; ++i) { + if (m_capabilities[i] == normCapa) return true; } @@ -581,56 +616,44 @@ bool IMAPConnection::hasCapability(const string& capa) } -bool IMAPConnection::hasCapability(const string& capa) const -{ - const string normCapa = utility::stringUtils::toUpper(capa); +void IMAPConnection::invalidateCapabilities() { - for (size_t i = 0, n = m_capabilities.size() ; i < n ; ++i) - { - if (m_capabilities[i] == normCapa) - return true; - } - - return false; -} - - -void IMAPConnection::invalidateCapabilities() -{ m_capabilities.clear(); m_capabilitiesFetched = false; } -void IMAPConnection::fetchCapabilities() -{ +void IMAPConnection::fetchCapabilities() { + IMAPCommand::CAPABILITY()->send(dynamicCast (shared_from_this())); scoped_ptr resp(m_parser->readResponse()); if (resp->response_done()->response_tagged()-> - resp_cond_state()->status() == IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() == IMAPParser::resp_cond_state::OK) { + processCapabilityResponseData(resp.get()); } } -bool IMAPConnection::processCapabilityResponseData(const IMAPParser::response* resp) -{ +bool IMAPConnection::processCapabilityResponseData(const IMAPParser::response* resp) { + const std::vector & respDataList = resp->continue_req_or_response_data(); - for (size_t i = 0 ; i < respDataList.size() ; ++i) - { - if (respDataList[i]->response_data() == NULL) + for (size_t i = 0 ; i < respDataList.size() ; ++i) { + + if (respDataList[i]->response_data() == NULL) { continue; + } const IMAPParser::capability_data* capaData = respDataList[i]->response_data()->capability_data(); - if (capaData == NULL) + if (capaData == NULL) { continue; + } processCapabilityResponseData(capaData); return true; @@ -640,18 +663,19 @@ bool IMAPConnection::processCapabilityResponseData(const IMAPParser::response* r } -void IMAPConnection::processCapabilityResponseData(const IMAPParser::capability_data* capaData) -{ +void IMAPConnection::processCapabilityResponseData(const IMAPParser::capability_data* capaData) { + std::vector res; std::vector caps = capaData->capabilities(); - for (unsigned int j = 0 ; j < caps.size() ; ++j) - { - if (caps[j]->auth_type()) + for (unsigned int j = 0 ; j < caps.size() ; ++j) { + + if (caps[j]->auth_type()) { res.push_back("AUTH=" + caps[j]->auth_type()->name()); - else + } else { res.push_back(utility::stringUtils::toUpper(caps[j]->atom()->value())); + } } m_capabilities = res; @@ -659,44 +683,46 @@ void IMAPConnection::processCapabilityResponseData(const IMAPParser::capability_ } -shared_ptr IMAPConnection::getAuthenticator() -{ +shared_ptr IMAPConnection::getAuthenticator() { + return m_auth; } -bool IMAPConnection::isConnected() const -{ - return (m_socket && m_socket->isConnected() && - (m_state == STATE_AUTHENTICATED || m_state == STATE_SELECTED)); +bool IMAPConnection::isConnected() const { + + return m_socket + && m_socket->isConnected() + && (m_state == STATE_AUTHENTICATED || m_state == STATE_SELECTED); } -bool IMAPConnection::isSecuredConnection() const -{ +bool IMAPConnection::isSecuredConnection() const { + return m_secured; } -shared_ptr IMAPConnection::getConnectionInfos() const -{ +shared_ptr IMAPConnection::getConnectionInfos() const { + return m_cntInfos; } -void IMAPConnection::disconnect() -{ - if (!isConnected()) +void IMAPConnection::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } internalDisconnect(); } -void IMAPConnection::internalDisconnect() -{ - if (isConnected()) - { +void IMAPConnection::internalDisconnect() { + + if (isConnected()) { + IMAPCommand::LOGOUT()->send(dynamicCast (shared_from_this())); m_socket->disconnect(); @@ -712,15 +738,15 @@ void IMAPConnection::internalDisconnect() } -void IMAPConnection::initHierarchySeparator() -{ +void IMAPConnection::initHierarchySeparator() { + IMAPCommand::LIST("", "")->send(dynamicCast (shared_from_this())); scoped_ptr resp(m_parser->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + internalDisconnect(); throw exceptions::command_error("LIST", resp->getErrorLog(), "bad response"); } @@ -730,34 +756,37 @@ void IMAPConnection::initHierarchySeparator() bool found = false; - for (unsigned int i = 0 ; !found && i < respDataList.size() ; ++i) - { - if (respDataList[i]->response_data() == NULL) + for (unsigned int i = 0 ; !found && i < respDataList.size() ; ++i) { + + if (respDataList[i]->response_data() == NULL) { continue; + } const IMAPParser::mailbox_data* mailboxData = static_cast (respDataList[i]->response_data())->mailbox_data(); - if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) + if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) { continue; + } - if (mailboxData->mailbox_list()->quoted_char() != '\0') - { + if (mailboxData->mailbox_list()->quoted_char() != '\0') { m_hierarchySeparator = mailboxData->mailbox_list()->quoted_char(); found = true; } } - if (!found) // default + if (!found) { // default m_hierarchySeparator = '/'; + } } -void IMAPConnection::sendCommand(const shared_ptr & cmd) -{ - if (!m_firstTag) +void IMAPConnection::sendCommand(const shared_ptr & cmd) { + + if (!m_firstTag) { ++(*m_tag); + } m_socket->send(*m_tag); m_socket->send(" "); @@ -766,8 +795,8 @@ void IMAPConnection::sendCommand(const shared_ptr & cmd) m_firstTag = false; - if (m_tracer) - { + if (m_tracer) { + std::ostringstream oss; oss << string(*m_tag) << " " << cmd->getText(); @@ -776,87 +805,87 @@ void IMAPConnection::sendCommand(const shared_ptr & cmd) } -void IMAPConnection::sendRaw(const byte_t* buffer, const size_t count) -{ +void IMAPConnection::sendRaw(const byte_t* buffer, const size_t count) { + m_socket->sendRaw(buffer, count); } -IMAPParser::response* IMAPConnection::readResponse(IMAPParser::literalHandler* lh) -{ - return (m_parser->readResponse(lh)); +IMAPParser::response* IMAPConnection::readResponse(IMAPParser::literalHandler* lh) { + + return m_parser->readResponse(lh); } -IMAPConnection::ProtocolStates IMAPConnection::state() const -{ - return (m_state); +IMAPConnection::ProtocolStates IMAPConnection::state() const { + + return m_state; } -void IMAPConnection::setState(const ProtocolStates state) -{ +void IMAPConnection::setState(const ProtocolStates state) { + m_state = state; } -char IMAPConnection::hierarchySeparator() const -{ - return (m_hierarchySeparator); +char IMAPConnection::hierarchySeparator() const { + + return m_hierarchySeparator; } -shared_ptr IMAPConnection::getStore() const -{ +shared_ptr IMAPConnection::getStore() const { + return m_store.lock(); } -shared_ptr IMAPConnection::getStore() -{ +shared_ptr IMAPConnection::getStore() { + return m_store.lock(); } -shared_ptr IMAPConnection::getSession() -{ +shared_ptr IMAPConnection::getSession() { + return m_store.lock()->getSession(); } -shared_ptr IMAPConnection::getSocket() const -{ +shared_ptr IMAPConnection::getSocket() const { + return m_socket; } -void IMAPConnection::setSocket(const shared_ptr & sok) -{ +void IMAPConnection::setSocket(const shared_ptr & sok) { + m_socket = sok; m_parser->setSocket(sok); } -shared_ptr IMAPConnection::getTracer() -{ +shared_ptr IMAPConnection::getTracer() { + return m_tracer; } -shared_ptr IMAPConnection::getTag() -{ +shared_ptr IMAPConnection::getTag() { + return m_tag; } -bool IMAPConnection::isMODSEQDisabled() const -{ +bool IMAPConnection::isMODSEQDisabled() const { + return m_noModSeq; } -void IMAPConnection::disableMODSEQ() -{ +void IMAPConnection::disableMODSEQ() { + m_noModSeq = true; } diff --git a/src/vmime/net/imap/IMAPConnection.hpp b/src/vmime/net/imap/IMAPConnection.hpp index 9a277f7c..99750d49 100644 --- a/src/vmime/net/imap/IMAPConnection.hpp +++ b/src/vmime/net/imap/IMAPConnection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,8 +52,8 @@ class IMAPStore; class IMAPCommand; -class VMIME_EXPORT IMAPConnection : public object, public enable_shared_from_this -{ +class VMIME_EXPORT IMAPConnection : public object, public enable_shared_from_this { + public: IMAPConnection(const shared_ptr & store, const shared_ptr & auth); @@ -65,8 +65,7 @@ public: void disconnect(); - enum ProtocolStates - { + enum ProtocolStates { STATE_NONE, STATE_NON_AUTHENTICATED, STATE_AUTHENTICATED, diff --git a/src/vmime/net/imap/IMAPFolder.cpp b/src/vmime/net/imap/IMAPFolder.cpp index a142f7f5..ec39fe3e 100644 --- a/src/vmime/net/imap/IMAPFolder.cpp +++ b/src/vmime/net/imap/IMAPFolder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,106 +52,119 @@ namespace net { namespace imap { -IMAPFolder::IMAPFolder(const folder::path& path, const shared_ptr & store, const shared_ptr & attribs) - : m_store(store), m_connection(store->connection()), m_path(path), - m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1), - m_open(false), m_attribs(attribs) -{ +IMAPFolder::IMAPFolder( + const folder::path& path, + const shared_ptr & store, + const shared_ptr & attribs +) + : m_store(store), + m_connection(store->connection()), + m_path(path), + m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), + m_mode(-1), + m_open(false), + m_attribs(attribs) { + store->registerFolder(this); m_status = make_shared (); } -IMAPFolder::~IMAPFolder() -{ - try - { +IMAPFolder::~IMAPFolder() { + + try { + shared_ptr store = m_store.lock(); - if (store) - { - if (m_open) + if (store) { + + if (m_open) { close(false); + } store->unregisterFolder(this); - } - else if (m_open) - { + + } else if (m_open) { + m_connection = null; onClose(); } - } - catch (...) - { + + } catch (...) { + // Don't throw in destructor } } -int IMAPFolder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +int IMAPFolder::getMode() const { - return (m_mode); + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + return m_mode; } -const folderAttributes IMAPFolder::getAttributes() -{ +const folderAttributes IMAPFolder::getAttributes() { + // Root folder - if (m_path.isEmpty()) - { + if (m_path.isEmpty()) { + folderAttributes attribs; attribs.setType(folderAttributes::TYPE_CONTAINS_FOLDERS); attribs.setFlags(folderAttributes::FLAG_HAS_CHILDREN | folderAttributes::FLAG_NO_OPEN); return attribs; - } - else - { - if (!m_attribs) + + } else { + + if (!m_attribs) { testExistAndGetType(); + } return *m_attribs; } } -const folder::path::component IMAPFolder::getName() const -{ - return (m_name); +const folder::path::component IMAPFolder::getName() const { + + return m_name; } -const folder::path IMAPFolder::getFullPath() const -{ - return (m_path); +const folder::path IMAPFolder::getFullPath() const { + + return m_path; } -void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) -{ +void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } // Ensure this folder is not already open in the same session for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == m_path) { throw exceptions::folder_already_open(); + } } // Open a connection for this folder shared_ptr connection = make_shared (store, store->getAuthenticator()); - try - { + try { + connection->connect(); // Emit the "SELECT" command @@ -167,8 +180,9 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) std::vector selectParams; - if (m_connection->hasCapability("CONDSTORE")) + if (m_connection->hasCapability("CONDSTORE")) { selectParams.push_back("CONDSTORE"); + } IMAPCommand::SELECT( mode == MODE_READ_ONLY, @@ -180,67 +194,68 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) scoped_ptr resp(connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("SELECT", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("SELECT", resp->getErrorLog(), "bad response"); } const std::vector & respDataList = resp->continue_req_or_response_data(); for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("SELECT", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("SELECT", resp->getErrorLog(), "invalid response"); } const IMAPParser::response_data* responseData = (*it)->response_data(); // OK Untagged responses: UNSEEN, PERMANENTFLAGS, UIDVALIDITY (optional) - if (responseData->resp_cond_state()) - { + if (responseData->resp_cond_state()) { + const IMAPParser::resp_text_code* code = responseData->resp_cond_state()->resp_text()->resp_text_code(); - if (code != NULL) - { - switch (code->type()) - { - case IMAPParser::resp_text_code::NOMODSEQ: + if (code != NULL) { - connection->disableMODSEQ(); - break; + switch (code->type()) { - default: + case IMAPParser::resp_text_code::NOMODSEQ: + + connection->disableMODSEQ(); + break; + + default: + + break; + } + } + + // Untagged responses: FLAGS, EXISTS, RECENT (required) + } else if (responseData->mailbox_data()) { + + switch (responseData->mailbox_data()->type()) { + + default: break; + + case IMAPParser::mailbox_data::FLAGS: { + + if (!m_attribs) { + m_attribs = make_shared (); + } + + IMAPUtils::mailboxFlagsToFolderAttributes( + connection, + responseData->mailbox_data()->mailbox_flag_list(), + *m_attribs + ); break; } } } - // Untagged responses: FLAGS, EXISTS, RECENT (required) - else if (responseData->mailbox_data()) - { - switch (responseData->mailbox_data()->type()) - { - default: break; - - case IMAPParser::mailbox_data::FLAGS: - { - if (!m_attribs) - m_attribs = make_shared (); - - IMAPUtils::mailboxFlagsToFolderAttributes - (connection, responseData->mailbox_data()->mailbox_flag_list(), *m_attribs); - - break; - } - - } - } } processStatusUpdate(resp.get()); @@ -249,49 +264,52 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) const IMAPParser::resp_text_code* respTextCode = resp->response_done()-> response_tagged()->resp_cond_state()->resp_text()->resp_text_code(); - if (respTextCode) - { + if (respTextCode) { + const int openMode = (respTextCode->type() == IMAPParser::resp_text_code::READ_WRITE) - ? MODE_READ_WRITE : MODE_READ_ONLY; + ? MODE_READ_WRITE + : MODE_READ_ONLY; if (failIfModeIsNotAvailable && - mode == MODE_READ_WRITE && openMode == MODE_READ_ONLY) - { + mode == MODE_READ_WRITE && openMode == MODE_READ_ONLY) { + throw exceptions::operation_not_supported(); } } - m_connection = connection; m_open = true; m_mode = mode; - } - catch (std::exception&) - { + + } catch (std::exception&) { + throw; } } -void IMAPFolder::close(const bool expunge) -{ +void IMAPFolder::close(const bool expunge) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - if (!isOpen()) + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } shared_ptr oldConnection = m_connection; // Emit the "CLOSE" command to expunge messages marked // as deleted (this is fastest than "EXPUNGE") - if (expunge) - { - if (m_mode == MODE_READ_ONLY) + if (expunge) { + + if (m_mode == MODE_READ_ONLY) { throw exceptions::operation_not_supported(); + } IMAPCommand::CLOSE()->send(oldConnection); } @@ -311,11 +329,11 @@ void IMAPFolder::close(const bool expunge) } -void IMAPFolder::onClose() -{ +void IMAPFolder::onClose() { + for (std::vector ::iterator it = m_messages.begin() ; - it != m_messages.end() ; ++it) - { + it != m_messages.end() ; ++it) { + (*it)->onFolderClosed(); } @@ -323,18 +341,19 @@ void IMAPFolder::onClose() } -void IMAPFolder::create(const folderAttributes& attribs) -{ +void IMAPFolder::create(const folderAttributes& attribs) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (isOpen()) + } else if (isOpen()) { throw exceptions::illegal_state("Folder is open"); - else if (exists()) + } else if (exists()) { throw exceptions::illegal_state("Folder already exists"); - else if (!store->isValidFolderName(m_name)) + } else if (!store->isValidFolderName(m_name)) { throw exceptions::invalid_folder_name(); + } // Emit the "CREATE" command // @@ -346,31 +365,33 @@ void IMAPFolder::create(const folderAttributes& attribs) string mailbox = IMAPUtils::pathToString (m_connection->hierarchySeparator(), getFullPath()); - if (attribs.getType() & folderAttributes::TYPE_CONTAINS_FOLDERS) + if (attribs.getType() & folderAttributes::TYPE_CONTAINS_FOLDERS) { mailbox += m_connection->hierarchySeparator(); + } std::vector createParams; - if (attribs.getSpecialUse() != folderAttributes::SPECIALUSE_NONE) - { - if (!m_connection->hasCapability("CREATE-SPECIAL-USE")) + if (attribs.getSpecialUse() != folderAttributes::SPECIALUSE_NONE) { + + if (!m_connection->hasCapability("CREATE-SPECIAL-USE")) { throw exceptions::operation_not_supported(); + } // C: t2 CREATE MySpecial (USE (\Drafts \Sent)) std::ostringstream oss; oss << "USE ("; - switch (attribs.getSpecialUse()) - { - case folderAttributes::SPECIALUSE_NONE: // should not happen - case folderAttributes::SPECIALUSE_ALL: oss << "\\All"; break; - case folderAttributes::SPECIALUSE_ARCHIVE: oss << "\\Archive"; break; - case folderAttributes::SPECIALUSE_DRAFTS: oss << "\\Drafts"; break; - case folderAttributes::SPECIALUSE_FLAGGED: oss << "\\Flagged"; break; - case folderAttributes::SPECIALUSE_JUNK: oss << "\\Junk"; break; - case folderAttributes::SPECIALUSE_SENT: oss << "\\Sent"; break; - case folderAttributes::SPECIALUSE_TRASH: oss << "\\Trash"; break; - case folderAttributes::SPECIALUSE_IMPORTANT: oss << "\\Important"; break; + switch (attribs.getSpecialUse()) { + + case folderAttributes::SPECIALUSE_NONE: // should not happen + case folderAttributes::SPECIALUSE_ALL: oss << "\\All"; break; + case folderAttributes::SPECIALUSE_ARCHIVE: oss << "\\Archive"; break; + case folderAttributes::SPECIALUSE_DRAFTS: oss << "\\Drafts"; break; + case folderAttributes::SPECIALUSE_FLAGGED: oss << "\\Flagged"; break; + case folderAttributes::SPECIALUSE_JUNK: oss << "\\Junk"; break; + case folderAttributes::SPECIALUSE_SENT: oss << "\\Sent"; break; + case folderAttributes::SPECIALUSE_TRASH: oss << "\\Trash"; break; + case folderAttributes::SPECIALUSE_IMPORTANT: oss << "\\Important"; break; } oss << ")"; @@ -384,34 +405,38 @@ void IMAPFolder::create(const folderAttributes& attribs) scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("CREATE", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("CREATE", resp->getErrorLog(), "bad response"); } // Notify folder created shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_CREATED, m_path, m_path); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_CREATED, + m_path, m_path + ); notifyFolder(event); } -void IMAPFolder::destroy() -{ +void IMAPFolder::destroy() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - if (isOpen()) + if (isOpen()) { throw exceptions::illegal_state("Folder is open"); + } - const string mailbox = IMAPUtils::pathToString - (m_connection->hierarchySeparator(), getFullPath()); + const string mailbox = IMAPUtils::pathToString( + m_connection->hierarchySeparator(), getFullPath() + ); IMAPCommand::DELETE(mailbox)->send(m_connection); @@ -419,35 +444,37 @@ void IMAPFolder::destroy() scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("DELETE", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("DELETE", resp->getErrorLog(), "bad response"); } // Notify folder deleted shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_DELETED, m_path, m_path); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_DELETED, + m_path, m_path + ); notifyFolder(event); } -bool IMAPFolder::exists() -{ +bool IMAPFolder::exists() { + shared_ptr store = m_store.lock(); - if (!isOpen() && !store) + if (!isOpen() && !store) { throw exceptions::illegal_state("Store disconnected"); + } return testExistAndGetType() != -1; } -int IMAPFolder::testExistAndGetType() -{ +int IMAPFolder::testExistAndGetType() { + // To test whether a folder exists, we simple list it using // the "LIST" command, and there should be one unique mailbox // with this name... @@ -467,17 +494,21 @@ int IMAPFolder::testExistAndGetType() // // ==> NO, does not exist - IMAPCommand::LIST("", IMAPUtils::pathToString - (m_connection->hierarchySeparator(), getFullPath()))->send(m_connection); + IMAPCommand::LIST( + "", + IMAPUtils::pathToString( + m_connection->hierarchySeparator(), + getFullPath() + ) + )->send(m_connection); scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("LIST", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("LIST", resp->getErrorLog(), "bad response"); } // Check whether the result mailbox list contains this folder @@ -488,23 +519,26 @@ int IMAPFolder::testExistAndGetType() attribs.setType(-1); for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("LIST", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("LIST", resp->getErrorLog(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = (*it)->response_data()->mailbox_data(); // We are only interested in responses of type "LIST" - if (mailboxData != NULL && mailboxData->type() == IMAPParser::mailbox_data::LIST) - { + if (mailboxData != NULL && + mailboxData->type() == IMAPParser::mailbox_data::LIST) { + // Get the folder type/flags at the same time - IMAPUtils::mailboxFlagsToFolderAttributes - (m_connection, mailboxData->mailbox_list()->mailbox_flag_list(), attribs); + IMAPUtils::mailboxFlagsToFolderAttributes( + m_connection, + mailboxData->mailbox_list()->mailbox_flag_list(), + attribs + ); } } @@ -514,31 +548,35 @@ int IMAPFolder::testExistAndGetType() } -bool IMAPFolder::isOpen() const -{ - return (m_open); +bool IMAPFolder::isOpen() const { + + return m_open; } -shared_ptr IMAPFolder::getMessage(const size_t num) -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +shared_ptr IMAPFolder::getMessage(const size_t num) { - if (num < 1 || num > m_status->getMessageCount()) + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + if (num < 1 || num > m_status->getMessageCount()) { throw exceptions::message_not_found(); + } return make_shared (dynamicCast (shared_from_this()), num); } -std::vector > IMAPFolder::getMessages(const messageSet& msgs) -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +std::vector > IMAPFolder::getMessages(const messageSet& msgs) { - if (msgs.isEmpty()) + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + if (msgs.isEmpty()) { return std::vector >(); + } std::vector > messages; @@ -565,8 +603,8 @@ std::vector > IMAPFolder::getMessages(const messageSet& ms scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + throw exceptions::command_error("UID FETCH ... UID", resp->getErrorLog(), "bad response"); } @@ -575,20 +613,20 @@ std::vector > IMAPFolder::getMessages(const messageSet& ms resp->continue_req_or_response_data(); for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("UID FETCH ... UID", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("UID FETCH ... UID", resp->getErrorLog(), "invalid response"); } const IMAPParser::message_data* messageData = (*it)->response_data()->message_data(); // We are only interested in responses of type "FETCH" - if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) + if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) { continue; + } // Get Process fetch response for this message const size_t msgNum = messageData->number(); @@ -598,17 +636,15 @@ std::vector > IMAPFolder::getMessages(const messageSet& ms const std::vector atts = messageData->msg_att()->items(); for (std::vector ::const_iterator - it = atts.begin() ; it != atts.end() ; ++it) - { - if ((*it)->type() == IMAPParser::msg_att_item::UID) - { + it = atts.begin() ; it != atts.end() ; ++it) { + + if ((*it)->type() == IMAPParser::msg_att_item::UID) { msgUID = (*it)->unique_id()->value(); break; } } - if (!msgUID.empty()) - { + if (!msgUID.empty()) { shared_ptr thisFolder = dynamicCast (shared_from_this()); messages.push_back(make_shared (thisFolder, msgNum, msgUID)); } @@ -618,50 +654,55 @@ std::vector > IMAPFolder::getMessages(const messageSet& ms } -size_t IMAPFolder::getMessageCount() -{ - if (!isOpen()) +size_t IMAPFolder::getMessageCount() { + + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } return m_status->getMessageCount(); } -vmime_uint32 IMAPFolder::getUIDValidity() const -{ - if (!isOpen()) +vmime_uint32 IMAPFolder::getUIDValidity() const { + + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } return m_status->getUIDValidity(); } -vmime_uint64 IMAPFolder::getHighestModSequence() const -{ - if (!isOpen()) +vmime_uint64 IMAPFolder::getHighestModSequence() const { + + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } return m_status->getHighestModSeq(); } -shared_ptr IMAPFolder::getFolder(const folder::path::component& name) -{ +shared_ptr IMAPFolder::getFolder(const folder::path::component& name) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - return shared_ptr (new IMAPFolder(m_path / name, store, shared_ptr ())); + return make_shared (m_path / name, store, shared_ptr ()); } -std::vector > IMAPFolder::getFolders(const bool recursive) -{ +std::vector > IMAPFolder::getFolders(const bool recursive) { + shared_ptr store = m_store.lock(); - if (!isOpen() && !store) + if (!isOpen() && !store) { throw exceptions::illegal_state("Store disconnected"); + } // Eg. List folders in '/foo/bar' // @@ -672,17 +713,22 @@ std::vector > IMAPFolder::getFolders(const bool recursive) shared_ptr cmd; - const string pathString = IMAPUtils::pathToString - (m_connection->hierarchySeparator(), getFullPath()); + const string pathString = IMAPUtils::pathToString( + m_connection->hierarchySeparator(), getFullPath() + ); + + if (recursive) { - if (recursive) - { cmd = IMAPCommand::LIST(pathString, "*"); - } - else - { - cmd = IMAPCommand::LIST - (pathString.empty() ? "" : (pathString + m_connection->hierarchySeparator()), "%"); + + } else { + + cmd = IMAPCommand::LIST( + pathString.empty() + ? "" + : (pathString + m_connection->hierarchySeparator()), + "%" + ); } cmd->send(m_connection); @@ -691,8 +737,8 @@ std::vector > IMAPFolder::getFolders(const bool recursive) scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + throw exceptions::command_error("LIST", resp->getErrorLog(), "bad response"); } @@ -703,57 +749,62 @@ std::vector > IMAPFolder::getFolders(const bool recursive) std::vector > v; for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("LIST", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("LIST", resp->getErrorLog(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = (*it)->response_data()->mailbox_data(); - if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) + if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) { continue; + } // Get folder path const class IMAPParser::mailbox* mailbox = mailboxData->mailbox_list()->mailbox(); - folder::path path = IMAPUtils::stringToPath - (mailboxData->mailbox_list()->quoted_char(), mailbox->name()); + folder::path path = IMAPUtils::stringToPath( + mailboxData->mailbox_list()->quoted_char(), mailbox->name() + ); + + if (recursive || m_path.isDirectParentOf(path)) { - if (recursive || m_path.isDirectParentOf(path)) - { // Append folder to list const class IMAPParser::mailbox_flag_list* mailbox_flag_list = mailboxData->mailbox_list()->mailbox_flag_list(); shared_ptr attribs = make_shared (); - IMAPUtils::mailboxFlagsToFolderAttributes - (m_connection, mailbox_flag_list, *attribs); + IMAPUtils::mailboxFlagsToFolderAttributes(m_connection, mailbox_flag_list, *attribs); - v.push_back(shared_ptr (new IMAPFolder(path, store, attribs))); + v.push_back(make_shared (path, store, attribs)); } } - return (v); + return v; } -void IMAPFolder::fetchMessages(std::vector >& msg, const fetchAttributes& options, - utility::progressListener* progress) -{ +void IMAPFolder::fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (msg.empty()) + if (msg.empty()) { return; + } // Build message numbers list std::vector list; @@ -761,24 +812,24 @@ void IMAPFolder::fetchMessages(std::vector >& msg, const f std::map > numberToMsg; - for (std::vector >::iterator it = msg.begin() ; it != msg.end() ; ++it) - { + for (std::vector >::iterator it = msg.begin() ; it != msg.end() ; ++it) { + list.push_back((*it)->getNumber()); numberToMsg[(*it)->getNumber()] = dynamicCast (*it); } // Send the request - IMAPUtils::buildFetchCommand - (m_connection, messageSet::byNumber(list), options)->send(m_connection); + IMAPUtils::buildFetchCommand( + m_connection, messageSet::byNumber(list), options + )->send(m_connection); // Get the response scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("FETCH", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("FETCH", resp->getErrorLog(), "bad response"); } const std::vector & respDataList = @@ -787,58 +838,62 @@ void IMAPFolder::fetchMessages(std::vector >& msg, const f const size_t total = msg.size(); size_t current = 0; - if (progress) + if (progress) { progress->start(total); + } + + try { - try - { for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("FETCH", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("FETCH", resp->getErrorLog(), "invalid response"); } const IMAPParser::message_data* messageData = (*it)->response_data()->message_data(); // We are only interested in responses of type "FETCH" - if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) + if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) { continue; + } // Process fetch response for this message const size_t num = messageData->number(); std::map >::iterator msg = numberToMsg.find(num); - if (msg != numberToMsg.end()) - { + if (msg != numberToMsg.end()) { + (*msg).second->processFetchResponse(options, messageData); - if (progress) + if (progress) { progress->progress(++current, total); + } } } - } - catch (...) - { - if (progress) + + } catch (...) { + + if (progress) { progress->stop(total); + } throw; } - if (progress) + if (progress) { progress->stop(total); + } processStatusUpdate(resp.get()); } -void IMAPFolder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) -{ +void IMAPFolder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) { + std::vector > msgs; msgs.push_back(msg); @@ -846,35 +901,37 @@ void IMAPFolder::fetchMessage(const shared_ptr & msg, const fetchAttrib } -std::vector > IMAPFolder::getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs) -{ +std::vector > IMAPFolder::getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (msgs.isEmpty()) + if (msgs.isEmpty()) { return std::vector >(); + } // Ensure we also get the UID for each message fetchAttributes attribsWithUID(attribs); attribsWithUID.add(fetchAttributes::UID); // Send the request - IMAPUtils::buildFetchCommand - (m_connection, msgs, attribsWithUID)->send(m_connection); + IMAPUtils::buildFetchCommand(m_connection, msgs, attribsWithUID)->send(m_connection); // Get the response scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("FETCH", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("FETCH", resp->getErrorLog(), "bad response"); } const std::vector & respDataList = @@ -883,20 +940,20 @@ std::vector > IMAPFolder::getAndFetchMessages std::vector > messages; for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("FETCH", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + + throw exceptions::command_error("FETCH", resp->getErrorLog(), "invalid response"); } const IMAPParser::message_data* messageData = (*it)->response_data()->message_data(); // We are only interested in responses of type "FETCH" - if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) + if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) { continue; + } // Get message number const size_t msgNum = messageData->number(); @@ -906,10 +963,9 @@ std::vector > IMAPFolder::getAndFetchMessages message::uid msgUID; for (std::vector ::const_iterator - it = atts.begin() ; it != atts.end() ; ++it) - { - if ((*it)->type() == IMAPParser::msg_att_item::UID) - { + it = atts.begin() ; it != atts.end() ; ++it) { + + if ((*it)->type() == IMAPParser::msg_att_item::UID) { msgUID = (*it)->unique_id()->value(); break; } @@ -931,8 +987,8 @@ std::vector > IMAPFolder::getAndFetchMessages } -int IMAPFolder::getFetchCapabilities() const -{ +int IMAPFolder::getFetchCapabilities() const { + return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | fetchAttributes::STRUCTURE | fetchAttributes::FLAGS | fetchAttributes::SIZE | fetchAttributes::FULL_HEADER | @@ -940,64 +996,71 @@ int IMAPFolder::getFetchCapabilities() const } -shared_ptr IMAPFolder::getParent() -{ - if (m_path.isEmpty()) +shared_ptr IMAPFolder::getParent() { + + if (m_path.isEmpty()) { + return null; - else - return shared_ptr ( - new IMAPFolder(m_path.getParent(), m_store.lock(), shared_ptr ()) + + } else { + + return make_shared ( + m_path.getParent(), m_store.lock(), shared_ptr () ); + } } -shared_ptr IMAPFolder::getStore() const -{ +shared_ptr IMAPFolder::getStore() const { + return m_store.lock(); } -shared_ptr IMAPFolder::getStore() -{ +shared_ptr IMAPFolder::getStore() { + return m_store.lock(); } -void IMAPFolder::registerMessage(IMAPMessage* msg) -{ +void IMAPFolder::registerMessage(IMAPMessage* msg) { + m_messages.push_back(msg); } -void IMAPFolder::unregisterMessage(IMAPMessage* msg) -{ +void IMAPFolder::unregisterMessage(IMAPMessage* msg) { + std::vector ::iterator it = std::find(m_messages.begin(), m_messages.end(), msg); - if (it != m_messages.end()) + if (it != m_messages.end()) { m_messages.erase(it); + } } -void IMAPFolder::onStoreDisconnected() -{ +void IMAPFolder::onStoreDisconnected() { + m_store.reset(); } -void IMAPFolder::deleteMessages(const messageSet& msgs) -{ +void IMAPFolder::deleteMessages(const messageSet& msgs) { + shared_ptr store = m_store.lock(); - if (msgs.isEmpty()) + if (msgs.isEmpty()) { throw exceptions::invalid_argument(); + } - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } // Send the request IMAPCommand::STORE( @@ -1009,22 +1072,25 @@ void IMAPFolder::deleteMessages(const messageSet& msgs) scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("STORE", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("STORE", resp->getErrorLog(), "bad response"); } processStatusUpdate(resp.get()); } -void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const int mode) -{ +void IMAPFolder::setMessageFlags( + const messageSet& msgs, + const int flags, + const int mode +) { + const std::vector flagList = IMAPUtils::messageFlagList(flags); - if (!flagList.empty()) - { + if (!flagList.empty()) { + // Send the request IMAPCommand::STORE(msgs, mode, flagList)->send(m_connection); @@ -1032,10 +1098,9 @@ void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("STORE", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("STORE", resp->getErrorLog(), "bad response"); } processStatusUpdate(resp.get()); @@ -1043,10 +1108,13 @@ void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const } -messageSet IMAPFolder::addMessage - (const shared_ptr & msg, const int flags, - vmime::datetime* date, utility::progressListener* progress) -{ +messageSet IMAPFolder::addMessage( + const shared_ptr & msg, + const int flags, + vmime::datetime* date, + utility::progressListener* progress +) { + std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); @@ -1059,18 +1127,23 @@ messageSet IMAPFolder::addMessage } -messageSet IMAPFolder::addMessage - (utility::inputStream& is, const size_t size, const int flags, - vmime::datetime* date, utility::progressListener* progress) -{ +messageSet IMAPFolder::addMessage( + utility::inputStream& is, + const size_t size, + const int flags, + vmime::datetime* date, + utility::progressListener* progress +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } // Send the request IMAPCommand::APPEND( @@ -1086,16 +1159,15 @@ messageSet IMAPFolder::addMessage = resp->continue_req_or_response_data(); for (std::vector ::const_iterator - it = respList.begin() ; !ok && (it != respList.end()) ; ++it) - { - if ((*it)->continue_req()) + it = respList.begin() ; !ok && (it != respList.end()) ; ++it) { + + if ((*it)->continue_req()) { ok = true; + } } - if (!ok) - { - throw exceptions::command_error("APPEND", - resp->getErrorLog(), "bad response"); + if (!ok) { + throw exceptions::command_error("APPEND", resp->getErrorLog(), "bad response"); } processStatusUpdate(resp.get()); @@ -1104,17 +1176,20 @@ messageSet IMAPFolder::addMessage const size_t total = size; size_t current = 0; - if (progress) + if (progress) { progress->start(total); + } - const size_t blockSize = std::min(is.getBlockSize(), - static_cast (m_connection->getSocket()->getBlockSize())); + const size_t blockSize = std::min( + is.getBlockSize(), + static_cast (m_connection->getSocket()->getBlockSize()) + ); std::vector vbuffer(blockSize); byte_t* buffer = &vbuffer.front(); - while (!is.eof()) - { + while (!is.eof()) { + // Read some data from the input stream const size_t read = is.read(buffer, blockSize); current += read; @@ -1123,26 +1198,28 @@ messageSet IMAPFolder::addMessage m_connection->sendRaw(buffer, read); // Notify progress - if (progress) + if (progress) { progress->progress(current, total); + } } m_connection->sendRaw(utility::stringUtils::bytesFromString("\r\n"), 2); - if (m_connection->getTracer()) + if (m_connection->getTracer()) { m_connection->getTracer()->traceSendBytes(current); + } - if (progress) + if (progress) { progress->stop(total); + } // Get the response scoped_ptr finalResp(m_connection->readResponse()); if (finalResp->isBad() || finalResp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("APPEND", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("APPEND", resp->getErrorLog(), "bad response"); } processStatusUpdate(finalResp.get()); @@ -1150,23 +1227,25 @@ messageSet IMAPFolder::addMessage const IMAPParser::resp_text_code* respTextCode = finalResp->response_done()->response_tagged()->resp_cond_state()->resp_text()->resp_text_code(); - if (respTextCode && respTextCode->type() == IMAPParser::resp_text_code::APPENDUID) + if (respTextCode && respTextCode->type() == IMAPParser::resp_text_code::APPENDUID) { return IMAPUtils::buildMessageSet(respTextCode->uid_set()); + } return messageSet::empty(); } -void IMAPFolder::expunge() -{ +void IMAPFolder::expunge() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } // Send the request IMAPCommand::EXPUNGE()->send(m_connection); @@ -1175,28 +1254,28 @@ void IMAPFolder::expunge() scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("EXPUNGE", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("EXPUNGE", resp->getErrorLog(), "bad response"); } processStatusUpdate(resp.get()); } -void IMAPFolder::rename(const folder::path& newPath) -{ +void IMAPFolder::rename(const folder::path& newPath) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (m_path.isEmpty() || newPath.isEmpty()) + } else if (m_path.isEmpty() || newPath.isEmpty()) { throw exceptions::illegal_operation("Cannot rename root folder"); - else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX") + } else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX") { throw exceptions::illegal_operation("Cannot rename 'INBOX' folder"); - else if (!store->isValidFolderName(newPath.getLastComponent())) + } else if (!store->isValidFolderName(newPath.getLastComponent())) { throw exceptions::invalid_folder_name(); + } // Send the request IMAPCommand::RENAME( @@ -1208,10 +1287,9 @@ void IMAPFolder::rename(const folder::path& newPath) scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("RENAME", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("RENAME", resp->getErrorLog(), "bad response"); } // Notify folder renamed @@ -1221,26 +1299,31 @@ void IMAPFolder::rename(const folder::path& newPath) m_name = newPath.getLastComponent(); shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_RENAMED, oldPath, newPath); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_RENAMED, + oldPath, + newPath + ); notifyFolder(event); // Notify sub-folders for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) { + folder::path oldPath((*it)->m_path); (*it)->m_path.renameParent(oldPath, newPath); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::folderEvent::TYPE_RENAMED, + oldPath, (*it)->m_path + ); (*it)->notifyFolder(event); } @@ -1250,14 +1333,15 @@ void IMAPFolder::rename(const folder::path& newPath) } -messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set) -{ +messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } // Send the request IMAPCommand::COPY( @@ -1269,10 +1353,9 @@ messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet& scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("COPY", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("COPY", resp->getErrorLog(), "bad response"); } processStatusUpdate(resp.get()); @@ -1280,15 +1363,16 @@ messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet& const IMAPParser::resp_text_code* respTextCode = resp->response_done()->response_tagged()->resp_cond_state()->resp_text()->resp_text_code(); - if (respTextCode && respTextCode->type() == IMAPParser::resp_text_code::COPYUID) + if (respTextCode && respTextCode->type() == IMAPParser::resp_text_code::COPYUID) { return IMAPUtils::buildMessageSet(respTextCode->uid_set2()); + } return messageSet::empty(); } -void IMAPFolder::status(size_t& count, size_t& unseen) -{ +void IMAPFolder::status(size_t& count, size_t& unseen) { + count = 0; unseen = 0; @@ -1299,12 +1383,13 @@ void IMAPFolder::status(size_t& count, size_t& unseen) } -shared_ptr IMAPFolder::getStatus() -{ +shared_ptr IMAPFolder::getStatus() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } // Build the attributes list std::vector attribs; @@ -1314,8 +1399,9 @@ shared_ptr IMAPFolder::getStatus() attribs.push_back("UIDNEXT"); attribs.push_back("UIDVALIDITY"); - if (m_connection->hasCapability("CONDSTORE")) + if (m_connection->hasCapability("CONDSTORE")) { attribs.push_back("HIGHESTMODSEQ"); + } // Send the request IMAPCommand::STATUS( @@ -1327,25 +1413,24 @@ shared_ptr IMAPFolder::getStatus() scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("STATUS", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("STATUS", resp->getErrorLog(), "bad response"); } const std::vector & respDataList = resp->continue_req_or_response_data(); for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() != NULL) - { + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() != NULL) { + const IMAPParser::response_data* responseData = (*it)->response_data(); if (responseData->mailbox_data() && - responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS) - { + responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS) { + shared_ptr status = make_shared (); status->updateFromResponse(responseData->mailbox_data()); @@ -1356,25 +1441,25 @@ shared_ptr IMAPFolder::getStatus() } } - throw exceptions::command_error("STATUS", - resp->getErrorLog(), "invalid response"); + throw exceptions::command_error("STATUS", resp->getErrorLog(), "invalid response"); } -void IMAPFolder::noop() -{ +void IMAPFolder::noop() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } IMAPCommand::NOOP()->send(m_connection); scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + throw exceptions::command_error("NOOP", resp->getErrorLog()); } @@ -1382,8 +1467,8 @@ void IMAPFolder::noop() } -std::vector IMAPFolder::getMessageNumbersStartingOnUID(const message::uid& uid) -{ +std::vector IMAPFolder::getMessageNumbersStartingOnUID(const message::uid& uid) { + // Send the request std::ostringstream uidSearchKey; uidSearchKey.imbue(std::locale::classic()); @@ -1398,22 +1483,20 @@ std::vector IMAPFolder::getMessageNumbersStartingOnUID(const message::u scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || - resp->response_done()->response_tagged()->resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("SEARCH", - resp->getErrorLog(), "bad response"); + resp->response_done()->response_tagged()->resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("SEARCH", resp->getErrorLog(), "bad response"); } const std::vector & respDataList = resp->continue_req_or_response_data(); + std::vector seqNumbers; for (std::vector ::const_iterator - it = respDataList.begin() ; it != respDataList.end() ; ++it) - { - if ((*it)->response_data() == NULL) - { - throw exceptions::command_error("SEARCH", - resp->getErrorLog(), "invalid response"); + it = respDataList.begin() ; it != respDataList.end() ; ++it) { + + if ((*it)->response_data() == NULL) { + throw exceptions::command_error("SEARCH", resp->getErrorLog(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = @@ -1421,16 +1504,16 @@ std::vector IMAPFolder::getMessageNumbersStartingOnUID(const message::u // We are only interested in responses of type "SEARCH" if (mailboxData == NULL || - mailboxData->type() != IMAPParser::mailbox_data::SEARCH) - { + mailboxData->type() != IMAPParser::mailbox_data::SEARCH) { + continue; } for (std::vector ::const_iterator it = mailboxData->search_nz_number_list().begin() ; it != mailboxData->search_nz_number_list().end(); - ++it) - { + ++it) { + seqNumbers.push_back((*it)->value()); } } @@ -1441,8 +1524,8 @@ std::vector IMAPFolder::getMessageNumbersStartingOnUID(const message::u } -void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) -{ +void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) { + std::vector > events; shared_ptr oldStatus = vmime::clone(m_status); @@ -1451,8 +1534,8 @@ void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) // Process tagged response if (resp->response_done() && resp->response_done()->response_tagged() && resp->response_done()->response_tagged() - ->resp_cond_state()->resp_text()->resp_text_code()) - { + ->resp_cond_state()->resp_text()->resp_text_code()) { + const IMAPParser::resp_text_code* code = resp->response_done()->response_tagged() ->resp_cond_state()->resp_text()->resp_text_code(); @@ -1463,66 +1546,77 @@ void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) // Process untagged responses for (std::vector ::const_iterator it = resp->continue_req_or_response_data().begin() ; - it != resp->continue_req_or_response_data().end() ; ++it) - { + it != resp->continue_req_or_response_data().end() ; ++it) { + if ((*it)->response_data() && (*it)->response_data()->resp_cond_state() && - (*it)->response_data()->resp_cond_state()->resp_text()->resp_text_code()) - { + (*it)->response_data()->resp_cond_state()->resp_text()->resp_text_code()) { + const IMAPParser::resp_text_code* code = (*it)->response_data()->resp_cond_state()->resp_text()->resp_text_code(); m_status->updateFromResponse(code); - } - else if ((*it)->response_data() && (*it)->response_data()->mailbox_data()) - { + + } else if ((*it)->response_data() && (*it)->response_data()->mailbox_data()) { + m_status->updateFromResponse((*it)->response_data()->mailbox_data()); // Update folder attributes, if available - if ((*it)->response_data()->mailbox_data()->type() == IMAPParser::mailbox_data::LIST) - { + if ((*it)->response_data()->mailbox_data()->type() == IMAPParser::mailbox_data::LIST) { + folderAttributes attribs; - IMAPUtils::mailboxFlagsToFolderAttributes - (m_connection, (*it)->response_data()->mailbox_data()->mailbox_list()->mailbox_flag_list(), attribs); + IMAPUtils::mailboxFlagsToFolderAttributes( + m_connection, + (*it)->response_data()->mailbox_data()->mailbox_list()->mailbox_flag_list(), + attribs + ); m_attribs = make_shared (attribs); } - } - else if ((*it)->response_data() && (*it)->response_data()->message_data()) - { + + } else if ((*it)->response_data() && (*it)->response_data()->message_data()) { + const IMAPParser::message_data* msgData = (*it)->response_data()->message_data(); const size_t msgNumber = msgData->number(); - if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::FETCH) - { + if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::FETCH) { + // Message changed for (std::vector ::iterator mit = - m_messages.begin() ; mit != m_messages.end() ; ++mit) - { - if ((*mit)->getNumber() == msgNumber) + m_messages.begin() ; mit != m_messages.end() ; ++mit) { + + if ((*mit)->getNumber() == msgNumber) { (*mit)->processFetchResponse(/* options */ 0, msgData); + } } - events.push_back(make_shared - (dynamicCast (shared_from_this()), - events::messageChangedEvent::TYPE_FLAGS, - std::vector (1, msgNumber))); - } - else if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::EXPUNGE) - { + events.push_back( + make_shared ( + dynamicCast (shared_from_this()), + events::messageChangedEvent::TYPE_FLAGS, + std::vector (1, msgNumber) + ) + ); + + } else if ((*it)->response_data()->message_data()->type() == IMAPParser::message_data::EXPUNGE) { + // A message has been expunged, renumber messages for (std::vector ::iterator jt = - m_messages.begin() ; jt != m_messages.end() ; ++jt) - { - if ((*jt)->getNumber() == msgNumber) + m_messages.begin() ; jt != m_messages.end() ; ++jt) { + + if ((*jt)->getNumber() == msgNumber) { (*jt)->setExpunged(); - else if ((*jt)->getNumber() > msgNumber) + } else if ((*jt)->getNumber() > msgNumber) { (*jt)->renumber((*jt)->getNumber() - 1); + } } - events.push_back(make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_REMOVED, - std::vector (1, msgNumber))); + events.push_back( + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_REMOVED, + std::vector (1, msgNumber) + ) + ); expungedMessageCount++; } @@ -1530,26 +1624,29 @@ void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) } // New messages arrived - if (m_status->getMessageCount() > oldStatus->getMessageCount() - expungedMessageCount) - { + if (m_status->getMessageCount() > oldStatus->getMessageCount() - expungedMessageCount) { + std::vector newMessageNumbers; for (size_t msgNumber = oldStatus->getMessageCount() - expungedMessageCount ; - msgNumber <= m_status->getMessageCount() ; ++msgNumber) - { + msgNumber <= m_status->getMessageCount() ; ++msgNumber) { + newMessageNumbers.push_back(msgNumber); } - events.push_back(make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_ADDED, - newMessageNumbers)); + events.push_back( + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + newMessageNumbers + ) + ); } // Dispatch notifications for (std::vector >::iterator evit = - events.begin() ; evit != events.end() ; ++evit) - { + events.begin() ; evit != events.end() ; ++evit) { + notifyEvent(*evit); } } diff --git a/src/vmime/net/imap/IMAPFolder.hpp b/src/vmime/net/imap/IMAPFolder.hpp index 15663232..3e6b04b5 100644 --- a/src/vmime/net/imap/IMAPFolder.hpp +++ b/src/vmime/net/imap/IMAPFolder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -54,19 +54,23 @@ class IMAPFolderStatus; /** IMAP folder implementation. */ +class VMIME_EXPORT IMAPFolder : public folder { -class VMIME_EXPORT IMAPFolder : public folder -{ private: friend class IMAPStore; friend class IMAPMessage; IMAPFolder(const IMAPFolder&); - IMAPFolder(const folder::path& path, const shared_ptr & store, const shared_ptr & attribs); public: + IMAPFolder( + const folder::path& path, + const shared_ptr & store, + const shared_ptr & attribs + ); + ~IMAPFolder(); int getMode() const; @@ -100,20 +104,26 @@ public: void deleteMessages(const messageSet& msgs); - void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + void setMessageFlags( + const messageSet& msgs, + const int flags, + const int mode = message::FLAG_MODE_SET + ); - messageSet addMessage - (const shared_ptr & msg, - const int flags = -1, - vmime::datetime* date = NULL, - utility::progressListener* progress = NULL); + messageSet addMessage( + const shared_ptr & msg, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); - messageSet addMessage - (utility::inputStream& is, - const size_t size, - const int flags = -1, - vmime::datetime* date = NULL, - utility::progressListener* progress = NULL); + messageSet addMessage( + utility::inputStream& is, + const size_t size, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); messageSet copyMessages(const folder::path& dest, const messageSet& msgs); @@ -130,11 +140,18 @@ public: shared_ptr getStore(); - void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress = NULL + ); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); - std::vector > getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs); + std::vector > getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs + ); int getFetchCapabilities() const; diff --git a/src/vmime/net/imap/IMAPFolderStatus.cpp b/src/vmime/net/imap/IMAPFolderStatus.cpp index 73e1dfed..1962c1ca 100644 --- a/src/vmime/net/imap/IMAPFolderStatus.cpp +++ b/src/vmime/net/imap/IMAPFolderStatus.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ IMAPFolderStatus::IMAPFolderStatus() m_recent(0), m_uidValidity(0), m_uidNext(0), - m_highestModSeq(0) -{ + m_highestModSeq(0) { + } @@ -53,166 +53,158 @@ IMAPFolderStatus::IMAPFolderStatus(const IMAPFolderStatus& other) m_recent(other.m_recent), m_uidValidity(other.m_uidValidity), m_uidNext(other.m_uidNext), - m_highestModSeq(other.m_highestModSeq) -{ + m_highestModSeq(other.m_highestModSeq) { + } -size_t IMAPFolderStatus::getMessageCount() const -{ +size_t IMAPFolderStatus::getMessageCount() const { + return m_count; } -size_t IMAPFolderStatus::getUnseenCount() const -{ +size_t IMAPFolderStatus::getUnseenCount() const { + return m_unseen; } -size_t IMAPFolderStatus::getRecentCount() const -{ +size_t IMAPFolderStatus::getRecentCount() const { + return m_recent; } -vmime_uint32 IMAPFolderStatus::getUIDValidity() const -{ +vmime_uint32 IMAPFolderStatus::getUIDValidity() const { + return m_uidValidity; } -vmime_uint32 IMAPFolderStatus::getUIDNext() const -{ +vmime_uint32 IMAPFolderStatus::getUIDNext() const { + return m_uidNext; } -vmime_uint64 IMAPFolderStatus::getHighestModSeq() const -{ +vmime_uint64 IMAPFolderStatus::getHighestModSeq() const { + return m_highestModSeq; } -shared_ptr IMAPFolderStatus::clone() const -{ +shared_ptr IMAPFolderStatus::clone() const { + return make_shared (*this); } -bool IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp) -{ +bool IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp) { + bool changed = false; - if (resp->type() == IMAPParser::mailbox_data::STATUS) - { + if (resp->type() == IMAPParser::mailbox_data::STATUS) { + const IMAPParser::status_att_list* statusAttList = resp->status_att_list(); for (std::vector ::const_iterator - jt = statusAttList->values().begin() ; jt != statusAttList->values().end() ; ++jt) - { - switch ((*jt)->type()) - { - case IMAPParser::status_att_val::MESSAGES: - { - const size_t count = - static_cast ((*jt)->value_as_number()->value()); + jt = statusAttList->values().begin() ; jt != statusAttList->values().end() ; ++jt) { - if (m_count != count) - { - m_count = count; - changed = true; + switch ((*jt)->type()) { + + case IMAPParser::status_att_val::MESSAGES: { + + const size_t count = + static_cast ((*jt)->value_as_number()->value()); + + if (m_count != count) { + m_count = count; + changed = true; + } + + break; } + case IMAPParser::status_att_val::UNSEEN: { - break; - } - case IMAPParser::status_att_val::UNSEEN: - { - const size_t unseen = - static_cast ((*jt)->value_as_number()->value()); + const size_t unseen = + static_cast ((*jt)->value_as_number()->value()); - if (m_unseen != unseen) - { - m_unseen = unseen; - changed = true; + if (m_unseen != unseen) { + m_unseen = unseen; + changed = true; + } + + break; } + case IMAPParser::status_att_val::RECENT: { - break; - } - case IMAPParser::status_att_val::RECENT: - { - const size_t recent = - static_cast ((*jt)->value_as_number()->value()); + const size_t recent = + static_cast ((*jt)->value_as_number()->value()); - if (m_recent != recent) - { - m_recent = recent; - changed = true; + if (m_recent != recent) { + m_recent = recent; + changed = true; + } + + break; } + case IMAPParser::status_att_val::UIDNEXT: { - break; - } - case IMAPParser::status_att_val::UIDNEXT: - { - const vmime_uint32 uidNext = - static_cast ((*jt)->value_as_number()->value()); + const vmime_uint32 uidNext = + static_cast ((*jt)->value_as_number()->value()); - if (m_uidNext != uidNext) - { - m_uidNext = uidNext; - changed = true; + if (m_uidNext != uidNext) { + m_uidNext = uidNext; + changed = true; + } + + break; } + case IMAPParser::status_att_val::UIDVALIDITY: { - break; - } - case IMAPParser::status_att_val::UIDVALIDITY: - { - const vmime_uint32 uidValidity = - static_cast ((*jt)->value_as_number()->value()); + const vmime_uint32 uidValidity = + static_cast ((*jt)->value_as_number()->value()); - if (m_uidValidity != uidValidity) - { - m_uidValidity = uidValidity; - changed = true; + if (m_uidValidity != uidValidity) { + m_uidValidity = uidValidity; + changed = true; + } + + break; } + case IMAPParser::status_att_val::HIGHESTMODSEQ: { - break; - } - case IMAPParser::status_att_val::HIGHESTMODSEQ: - { - const vmime_uint64 highestModSeq = - static_cast ((*jt)->value_as_mod_sequence_value()->value()); + const vmime_uint64 highestModSeq = + static_cast ((*jt)->value_as_mod_sequence_value()->value()); - if (m_highestModSeq != highestModSeq) - { - m_highestModSeq = highestModSeq; - changed = true; + if (m_highestModSeq != highestModSeq) { + m_highestModSeq = highestModSeq; + changed = true; + } + + break; } - break; - } - } } - } - else if (resp->type() == IMAPParser::mailbox_data::EXISTS) - { + + } else if (resp->type() == IMAPParser::mailbox_data::EXISTS) { + const size_t count = static_cast (resp->number()->value()); - if (m_count != count) - { + if (m_count != count) { m_count = count; changed = true; } - } - else if (resp->type() == IMAPParser::mailbox_data::RECENT) - { + + } else if (resp->type() == IMAPParser::mailbox_data::RECENT) { + const size_t recent = static_cast (resp->number()->value()); - if (m_recent != recent) - { + if (m_recent != recent) { m_recent = recent; changed = true; } @@ -222,77 +214,73 @@ bool IMAPFolderStatus::updateFromResponse(const IMAPParser::mailbox_data* resp) } -bool IMAPFolderStatus::updateFromResponse(const IMAPParser::resp_text_code* resp) -{ +bool IMAPFolderStatus::updateFromResponse(const IMAPParser::resp_text_code* resp) { + bool changed = false; - switch (resp->type()) - { - case IMAPParser::resp_text_code::UIDVALIDITY: - { - const vmime_uint32 uidValidity = - static_cast (resp->nz_number()->value()); + switch (resp->type()) { - if (m_uidValidity != uidValidity) - { - m_uidValidity = uidValidity; - changed = true; + case IMAPParser::resp_text_code::UIDVALIDITY: { + + const vmime_uint32 uidValidity = + static_cast (resp->nz_number()->value()); + + if (m_uidValidity != uidValidity) { + m_uidValidity = uidValidity; + changed = true; + } + + break; } + case IMAPParser::resp_text_code::UIDNEXT: { - break; - } - case IMAPParser::resp_text_code::UIDNEXT: - { - const vmime_uint32 uidNext = - static_cast (resp->nz_number()->value()); + const vmime_uint32 uidNext = + static_cast (resp->nz_number()->value()); - if (m_uidNext != uidNext) - { - m_uidNext = uidNext; - changed = true; + if (m_uidNext != uidNext) { + m_uidNext = uidNext; + changed = true; + } + + break; } + case IMAPParser::resp_text_code::UNSEEN: { - break; - } - case IMAPParser::resp_text_code::UNSEEN: - { - const size_t unseen = - static_cast (resp->nz_number()->value()); + const size_t unseen = + static_cast (resp->nz_number()->value()); - if (m_unseen != unseen) - { - m_unseen = unseen; - changed = true; + if (m_unseen != unseen) + { + m_unseen = unseen; + changed = true; + } + + break; } + case IMAPParser::resp_text_code::HIGHESTMODSEQ: { - break; - } - case IMAPParser::resp_text_code::HIGHESTMODSEQ: - { - const vmime_uint64 highestModSeq = - static_cast (resp->mod_sequence_value()->value()); + const vmime_uint64 highestModSeq = + static_cast (resp->mod_sequence_value()->value()); - if (m_highestModSeq != highestModSeq) - { - m_highestModSeq = highestModSeq; - changed = true; + if (m_highestModSeq != highestModSeq) { + m_highestModSeq = highestModSeq; + changed = true; + } + + break; } + case IMAPParser::resp_text_code::NOMODSEQ: { - break; - } - case IMAPParser::resp_text_code::NOMODSEQ: - { - if (m_highestModSeq != 0) - { - m_highestModSeq = 0; - changed = true; + if (m_highestModSeq != 0) { + m_highestModSeq = 0; + changed = true; + } + + break; } + default: - break; - } - default: - - break; + break; } return changed; diff --git a/src/vmime/net/imap/IMAPFolderStatus.hpp b/src/vmime/net/imap/IMAPFolderStatus.hpp index 63143548..846ad771 100644 --- a/src/vmime/net/imap/IMAPFolderStatus.hpp +++ b/src/vmime/net/imap/IMAPFolderStatus.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,9 +43,8 @@ namespace imap { /** Holds the status of an IMAP folder. */ +class VMIME_EXPORT IMAPFolderStatus : public folderStatus { -class VMIME_EXPORT IMAPFolderStatus : public folderStatus -{ public: IMAPFolderStatus(); diff --git a/src/vmime/net/imap/IMAPMessage.cpp b/src/vmime/net/imap/IMAPMessage.cpp index 87f78f38..b09c9c19 100644 --- a/src/vmime/net/imap/IMAPMessage.cpp +++ b/src/vmime/net/imap/IMAPMessage.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -56,25 +56,25 @@ namespace imap { // IMAPMessage_literalHandler // -class IMAPMessage_literalHandler : public IMAPParser::literalHandler -{ +class IMAPMessage_literalHandler : public IMAPParser::literalHandler { + public: - IMAPMessage_literalHandler(utility::outputStream& os, utility::progressListener* progress) - { + IMAPMessage_literalHandler(utility::outputStream& os, utility::progressListener* progress) { + m_target = shared_ptr (new targetStream(progress, os)); } - shared_ptr targetFor(const IMAPParser::component& comp, const int /* data */) - { - if (typeid(comp) == typeid(IMAPParser::msg_att_item)) - { + shared_ptr targetFor(const IMAPParser::component& comp, const int /* data */) { + + if (typeid(comp) == typeid(IMAPParser::msg_att_item)) { + const int type = static_cast (comp).type(); if (type == IMAPParser::msg_att_item::BODY_SECTION || - type == IMAPParser::msg_att_item::RFC822_TEXT) - { + type == IMAPParser::msg_att_item::RFC822_TEXT) { + return m_target; } } @@ -82,8 +82,8 @@ public: return shared_ptr (); } - shared_ptr getTarget() - { + shared_ptr getTarget() { + return m_target; } @@ -101,152 +101,187 @@ private: // -IMAPMessage::IMAPMessage(const shared_ptr & folder, const size_t num) - : m_folder(folder), m_num(num), m_size(-1U), m_flags(FLAG_UNDEFINED), - m_expunged(false), m_modseq(0), m_structure(null) -{ +IMAPMessage::IMAPMessage( + const shared_ptr & folder, + const size_t num +) + : m_folder(folder), + m_num(num), + m_size(-1U), + m_flags(FLAG_UNDEFINED), + m_expunged(false), + m_modseq(0), + m_structure(null) { + folder->registerMessage(this); } -IMAPMessage::IMAPMessage(const shared_ptr & folder, const size_t num, const uid& uid) - : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), - m_expunged(false), m_uid(uid), m_modseq(0), m_structure(null) -{ +IMAPMessage::IMAPMessage( + const shared_ptr & folder, + const size_t num, + const uid& uid +) + : m_folder(folder), + m_num(num), + m_size(-1), + m_flags(FLAG_UNDEFINED), + m_expunged(false), + m_uid(uid), + m_modseq(0), + m_structure(null) { + folder->registerMessage(this); } -IMAPMessage::~IMAPMessage() -{ - try - { +IMAPMessage::~IMAPMessage() { + + try { + shared_ptr folder = m_folder.lock(); - if (folder) + if (folder) { folder->unregisterMessage(this); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void IMAPMessage::onFolderClosed() -{ +void IMAPMessage::onFolderClosed() { + m_folder.reset(); } -size_t IMAPMessage::getNumber() const -{ - return (m_num); +size_t IMAPMessage::getNumber() const { + + return m_num; } -const message::uid IMAPMessage::getUID() const -{ +const message::uid IMAPMessage::getUID() const { + return m_uid; } -vmime_uint64 IMAPMessage::getModSequence() const -{ +vmime_uint64 IMAPMessage::getModSequence() const { + return m_modseq; } -size_t IMAPMessage::getSize() const -{ - if (m_size == -1U) - throw exceptions::unfetched_object(); +size_t IMAPMessage::getSize() const { - return (m_size); + if (m_size == -1U) { + throw exceptions::unfetched_object(); + } + + return m_size; } -bool IMAPMessage::isExpunged() const -{ - return (m_expunged); +bool IMAPMessage::isExpunged() const { + + return m_expunged; } -int IMAPMessage::getFlags() const -{ - if (m_flags == FLAG_UNDEFINED) - throw exceptions::unfetched_object(); +int IMAPMessage::getFlags() const { - return (m_flags); + if (m_flags == FLAG_UNDEFINED) { + throw exceptions::unfetched_object(); + } + + return m_flags; } -shared_ptr IMAPMessage::getStructure() const -{ - if (m_structure == NULL) +shared_ptr IMAPMessage::getStructure() const { + + if (m_structure == NULL) { throw exceptions::unfetched_object(); + } return m_structure; } -shared_ptr IMAPMessage::getStructure() -{ - if (m_structure == NULL) +shared_ptr IMAPMessage::getStructure() { + + if (m_structure == NULL) { throw exceptions::unfetched_object(); + } return m_structure; } -shared_ptr IMAPMessage::getHeader() const -{ - if (m_header == NULL) +shared_ptr IMAPMessage::getHeader() const { + + if (m_header == NULL) { throw exceptions::unfetched_object(); + } - return (m_header); + return m_header; } -void IMAPMessage::extract - (utility::outputStream& os, - utility::progressListener* progress, - const size_t start, const size_t length, - const bool peek) const -{ +void IMAPMessage::extract( + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const bool peek +) const { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::folder_not_found(); + } - extractImpl(null, os, progress, start, length, - EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0)); + extractImpl( + null, os, progress, start, length, + EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0) + ); } -void IMAPMessage::extractPart - (const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress, - const size_t start, const size_t length, - const bool peek) const -{ +void IMAPMessage::extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const bool peek +) const { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::folder_not_found(); + } - extractImpl(p, os, progress, start, length, - EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0)); + extractImpl( + p, os, progress, start, length, + EXTRACT_HEADER | EXTRACT_BODY | (peek ? EXTRACT_PEEK : 0) + ); } -void IMAPMessage::fetchPartHeader(const shared_ptr & p) -{ +void IMAPMessage::fetchPartHeader(const shared_ptr & p) { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::folder_not_found(); + } std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); @@ -257,10 +292,10 @@ void IMAPMessage::fetchPartHeader(const shared_ptr & p) } -void IMAPMessage::fetchPartHeaderForStructure(const shared_ptr & str) -{ - for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i) - { +void IMAPMessage::fetchPartHeaderForStructure(const shared_ptr & str) { + + for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i) { + shared_ptr part = str->getPartAt(i); // Fetch header of current part @@ -272,42 +307,43 @@ void IMAPMessage::fetchPartHeaderForStructure(const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress, - const size_t start, const size_t length, - const int extractFlags) const -{ +size_t IMAPMessage::extractImpl( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const int extractFlags +) const { + shared_ptr folder = m_folder.lock(); IMAPMessage_literalHandler literalHandler(os, progress); - if (length == 0) + if (length == 0) { return 0; + } // Construct section identifier std::ostringstream section; section.imbue(std::locale::classic()); - if (p != NULL) - { + if (p != NULL) { + shared_ptr currentPart = dynamicCast (p); std::vector numbers; numbers.push_back(currentPart->getNumber()); currentPart = currentPart->getParent(); - while (currentPart != NULL) - { + while (currentPart != NULL) { numbers.push_back(currentPart->getNumber()); currentPart = currentPart->getParent(); } numbers.erase(numbers.end() - 1); - for (std::vector ::reverse_iterator it = numbers.rbegin() ; it != numbers.rend() ; ++it) - { + for (std::vector ::reverse_iterator it = numbers.rbegin() ; it != numbers.rend() ; ++it) { if (it != numbers.rbegin()) section << "."; section << (*it + 1); } @@ -327,53 +363,57 @@ size_t IMAPMessage::extractImpl bodyDesc << "BODY"; - if (extractFlags & EXTRACT_PEEK) + if (extractFlags & EXTRACT_PEEK) { bodyDesc << ".PEEK"; + } bodyDesc << "["; - if (section.str().empty()) - { + if (section.str().empty()) { + // header + body - if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY)) + if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY)) { bodyDesc << ""; // body only - else if (extractFlags & EXTRACT_BODY) + } else if (extractFlags & EXTRACT_BODY) { bodyDesc << "TEXT"; // header only - else if (extractFlags & EXTRACT_HEADER) + } else if (extractFlags & EXTRACT_HEADER) { bodyDesc << "HEADER"; - } - else - { + } + + } else { + bodyDesc << section.str(); // header + body - if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY)) - { + if ((extractFlags & EXTRACT_HEADER) && (extractFlags & EXTRACT_BODY)) { + // First, extract header std::ostringstream header; utility::outputStreamAdapter headerStream(header); - const size_t headerLength = extractImpl - (p, headerStream, /* progress */ NULL, - /* start */ 0, /* length */ -1, extractFlags & ~EXTRACT_BODY); + const size_t headerLength = extractImpl( + p, headerStream, /* progress */ NULL, + /* start */ 0, /* length */ -1, extractFlags & ~EXTRACT_BODY + ); size_t s = start; size_t l = length; - if (s < headerLength) - { - if (l == static_cast (-1)) - { + if (s < headerLength) { + + if (l == static_cast (-1)) { + os.write(header.str().data() + s, headerLength - s); - } - else - { + + } else { + size_t headerCopyLength = l; - if (start + headerCopyLength > headerLength) + if (start + headerCopyLength > headerLength) { headerCopyLength = headerLength - start; + } os.write(header.str().data() + s, headerCopyLength); @@ -381,30 +421,31 @@ size_t IMAPMessage::extractImpl } s = 0; - } - else - { + + } else { + s -= headerLength; } // Then, extract body return extractImpl(p, os, progress, s, l, extractFlags & ~EXTRACT_HEADER); - } + // header only - else if (extractFlags & EXTRACT_HEADER) - { + } else if (extractFlags & EXTRACT_HEADER) { + bodyDesc << ".MIME"; // "MIME" not "HEADER" for parts } } bodyDesc << "]"; - if (start != 0 || length != static_cast (-1)) - { - if (length == static_cast (-1)) + if (start != 0 || length != static_cast (-1)) { + + if (length == static_cast (-1)) { bodyDesc << "<" << start << "." << static_cast (-1) << ">"; - else + } else { bodyDesc << "<" << start << "." << length << ">"; + } } std::vector fetchParams; @@ -417,19 +458,16 @@ size_t IMAPMessage::extractImpl )->send(folder->m_connection); // Get the response - scoped_ptr resp - (folder->m_connection->readResponse(&literalHandler)); + scoped_ptr resp(folder->m_connection->readResponse(&literalHandler)); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { - throw exceptions::command_error("FETCH", - resp->getErrorLog(), "bad response"); + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + + throw exceptions::command_error("FETCH", resp->getErrorLog(), "bad response"); } - if (extractFlags & EXTRACT_BODY) - { + if (extractFlags & EXTRACT_BODY) { // TODO: update the flags (eg. flag "\Seen" may have been set) } @@ -437,9 +475,11 @@ size_t IMAPMessage::extractImpl } -int IMAPMessage::processFetchResponse - (const fetchAttributes& options, const IMAPParser::message_data* msgData) -{ +int IMAPMessage::processFetchResponse( + const fetchAttributes& options, + const IMAPParser::message_data* msgData +) { + shared_ptr folder = m_folder.lock(); // Get message attributes @@ -447,138 +487,142 @@ int IMAPMessage::processFetchResponse int changes = 0; for (std::vector ::const_iterator - it = atts.begin() ; it != atts.end() ; ++it) - { - switch ((*it)->type()) - { - case IMAPParser::msg_att_item::FLAGS: - { - int flags = IMAPUtils::messageFlagsFromFlags((*it)->flag_list()); + it = atts.begin() ; it != atts.end() ; ++it) { - if (m_flags != flags) - { - m_flags = flags; - changes |= events::messageChangedEvent::TYPE_FLAGS; + switch ((*it)->type()) { + + case IMAPParser::msg_att_item::FLAGS: { + + int flags = IMAPUtils::messageFlagsFromFlags((*it)->flag_list()); + + if (m_flags != flags) { + m_flags = flags; + changes |= events::messageChangedEvent::TYPE_FLAGS; + } + + break; } + case IMAPParser::msg_att_item::UID: { - break; - } - case IMAPParser::msg_att_item::UID: - { - m_uid = (*it)->unique_id()->value(); - break; - } - case IMAPParser::msg_att_item::MODSEQ: - { - m_modseq = (*it)->mod_sequence_value()->value(); - break; - } - case IMAPParser::msg_att_item::ENVELOPE: - { - if (!options.has(fetchAttributes::FULL_HEADER)) - { - const IMAPParser::envelope* env = (*it)->envelope(); - shared_ptr hdr = getOrCreateHeader(); - - // Date - hdr->Date()->setValue(env->env_date()->value()); - - // Subject - text subject; - text::decodeAndUnfold(env->env_subject()->value(), &subject); - - hdr->Subject()->setValue(subject); - - // From - mailboxList from; - IMAPUtils::convertAddressList(*(env->env_from()), from); - - if (!from.isEmpty()) - hdr->From()->setValue(*(from.getMailboxAt(0))); - - // To - mailboxList to; - IMAPUtils::convertAddressList(*(env->env_to()), to); - - hdr->To()->setValue(to.toAddressList()); - - // Sender - mailboxList sender; - IMAPUtils::convertAddressList(*(env->env_sender()), sender); - - if (!sender.isEmpty()) - hdr->Sender()->setValue(*(sender.getMailboxAt(0))); - - // Reply-to - mailboxList replyTo; - IMAPUtils::convertAddressList(*(env->env_reply_to()), replyTo); - - if (!replyTo.isEmpty()) - hdr->ReplyTo()->setValue(*(replyTo.getMailboxAt(0))); - - // Cc - mailboxList cc; - IMAPUtils::convertAddressList(*(env->env_cc()), cc); - - if (!cc.isEmpty()) - hdr->Cc()->setValue(cc.toAddressList()); - - // Bcc - mailboxList bcc; - IMAPUtils::convertAddressList(*(env->env_bcc()), bcc); - - if (!bcc.isEmpty()) - hdr->Bcc()->setValue(bcc.toAddressList()); + m_uid = (*it)->unique_id()->value(); + break; } + case IMAPParser::msg_att_item::MODSEQ: { - break; - } - case IMAPParser::msg_att_item::BODY_STRUCTURE: - { - m_structure = make_shared ((*it)->body()); - break; - } - case IMAPParser::msg_att_item::RFC822_HEADER: - { - getOrCreateHeader()->parse((*it)->nstring()->value()); - break; - } - case IMAPParser::msg_att_item::RFC822_SIZE: - { - m_size = static_cast ((*it)->number()->value()); - break; - } - case IMAPParser::msg_att_item::BODY_SECTION: - { - if (!options.has(fetchAttributes::FULL_HEADER)) - { - if ((*it)->section()->section_text1() && - (*it)->section()->section_text1()->type() - == IMAPParser::section_text::HEADER_FIELDS) - { - header tempHeader; - tempHeader.parse((*it)->nstring()->value()); + m_modseq = (*it)->mod_sequence_value()->value(); + break; + } + case IMAPParser::msg_att_item::ENVELOPE: { - vmime::header& hdr = *getOrCreateHeader(); - std::vector > fields = tempHeader.getFieldList(); + if (!options.has(fetchAttributes::FULL_HEADER)) { - for (std::vector >::const_iterator jt = fields.begin() ; - jt != fields.end() ; ++jt) - { - hdr.appendField(vmime::clone(*jt)); + const IMAPParser::envelope* env = (*it)->envelope(); + shared_ptr hdr = getOrCreateHeader(); + + // Date + hdr->Date()->setValue(env->env_date()->value()); + + // Subject + text subject; + text::decodeAndUnfold(env->env_subject()->value(), &subject); + + hdr->Subject()->setValue(subject); + + // From + mailboxList from; + IMAPUtils::convertAddressList(*(env->env_from()), from); + + if (!from.isEmpty()) { + hdr->From()->setValue(*(from.getMailboxAt(0))); + } + + // To + mailboxList to; + IMAPUtils::convertAddressList(*(env->env_to()), to); + + hdr->To()->setValue(to.toAddressList()); + + // Sender + mailboxList sender; + IMAPUtils::convertAddressList(*(env->env_sender()), sender); + + if (!sender.isEmpty()) { + hdr->Sender()->setValue(*(sender.getMailboxAt(0))); + } + + // Reply-to + mailboxList replyTo; + IMAPUtils::convertAddressList(*(env->env_reply_to()), replyTo); + + if (!replyTo.isEmpty()) { + hdr->ReplyTo()->setValue(*(replyTo.getMailboxAt(0))); + } + + // Cc + mailboxList cc; + IMAPUtils::convertAddressList(*(env->env_cc()), cc); + + if (!cc.isEmpty()) { + hdr->Cc()->setValue(cc.toAddressList()); + } + + // Bcc + mailboxList bcc; + IMAPUtils::convertAddressList(*(env->env_bcc()), bcc); + + if (!bcc.isEmpty()) { + hdr->Bcc()->setValue(bcc.toAddressList()); } } - } - break; - } - case IMAPParser::msg_att_item::INTERNALDATE: - case IMAPParser::msg_att_item::RFC822: - case IMAPParser::msg_att_item::RFC822_TEXT: - case IMAPParser::msg_att_item::BODY: - { - break; - } + break; + } + case IMAPParser::msg_att_item::BODY_STRUCTURE: { + + m_structure = make_shared ((*it)->body()); + break; + } + case IMAPParser::msg_att_item::RFC822_HEADER: { + + getOrCreateHeader()->parse((*it)->nstring()->value()); + break; + } + case IMAPParser::msg_att_item::RFC822_SIZE: { + + m_size = static_cast ((*it)->number()->value()); + break; + } + case IMAPParser::msg_att_item::BODY_SECTION: { + + if (!options.has(fetchAttributes::FULL_HEADER)) { + + if ((*it)->section()->section_text1() && + (*it)->section()->section_text1()->type() + == IMAPParser::section_text::HEADER_FIELDS) { + + header tempHeader; + tempHeader.parse((*it)->nstring()->value()); + + vmime::header& hdr = *getOrCreateHeader(); + std::vector > fields = tempHeader.getFieldList(); + + for (std::vector >::const_iterator jt = fields.begin() ; + jt != fields.end() ; ++jt) { + + hdr.appendField(vmime::clone(*jt)); + } + } + } + + break; + } + case IMAPParser::msg_att_item::INTERNALDATE: + case IMAPParser::msg_att_item::RFC822: + case IMAPParser::msg_att_item::RFC822_TEXT: + case IMAPParser::msg_att_item::BODY: { + + break; + } } } @@ -587,34 +631,40 @@ int IMAPMessage::processFetchResponse } -shared_ptr
IMAPMessage::getOrCreateHeader() -{ - if (m_header != NULL) - return (m_header); - else - return (m_header = make_shared
()); +shared_ptr
IMAPMessage::getOrCreateHeader() { + + if (m_header != NULL) { + return m_header; + } else { + return m_header = make_shared
(); + } } -void IMAPMessage::setFlags(const int flags, const int mode) -{ +void IMAPMessage::setFlags(const int flags, const int mode) { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::folder_not_found(); + } - if (!m_uid.empty()) + if (!m_uid.empty()) { folder->setMessageFlags(messageSet::byUID(m_uid), flags, mode); - else + } else { folder->setMessageFlags(messageSet::byNumber(m_num), flags, mode); + } } -void IMAPMessage::constructParsedMessage - (const shared_ptr & parentPart, const shared_ptr & str, int level) -{ - if (level == 0) - { +void IMAPMessage::constructParsedMessage( + const shared_ptr & parentPart, + const shared_ptr & str, + int level +) { + + if (level == 0) { + shared_ptr part = str->getPartAt(0); // Copy header @@ -622,17 +672,19 @@ void IMAPMessage::constructParsedMessage parentPart->getHeader()->copyFrom(*hdr); // Initialize body - parentPart->getBody()->setContents - (make_shared - (dynamicCast (shared_from_this()), - part, parentPart->getBody()->getEncoding())); + parentPart->getBody()->setContents( + make_shared ( + dynamicCast (shared_from_this()), + part, parentPart->getBody()->getEncoding() + ) + ); constructParsedMessage(parentPart, part->getStructure(), 1); - } - else - { - for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i) - { + + } else { + + for (size_t i = 0, n = str->getPartCount() ; i < n ; ++i) { + shared_ptr part = str->getPartAt(i); shared_ptr childPart = make_shared (); @@ -642,10 +694,12 @@ void IMAPMessage::constructParsedMessage childPart->getHeader()->copyFrom(*hdr); // Initialize body - childPart->getBody()->setContents - (make_shared - (dynamicCast (shared_from_this()), - part, childPart->getBody()->getEncoding())); + childPart->getBody()->setContents( + make_shared ( + dynamicCast (shared_from_this()), + part, childPart->getBody()->getEncoding() + ) + ); // Add child part parentPart->getBody()->appendPart(childPart); @@ -657,22 +711,23 @@ void IMAPMessage::constructParsedMessage } -shared_ptr IMAPMessage::getParsedMessage() -{ +shared_ptr IMAPMessage::getParsedMessage() { + // Fetch structure shared_ptr structure; - try - { + try { + structure = getStructure(); - } - catch (exceptions::unfetched_object&) - { + + } catch (exceptions::unfetched_object&) { + std::vector > msgs; msgs.push_back(dynamicCast (shared_from_this())); - m_folder.lock()->fetchMessages - (msgs, fetchAttributes(fetchAttributes::STRUCTURE), /* progress */ NULL); + m_folder.lock()->fetchMessages( + msgs, fetchAttributes(fetchAttributes::STRUCTURE), /* progress */ NULL + ); structure = getStructure(); } @@ -689,14 +744,14 @@ shared_ptr IMAPMessage::getParsedMessage() } -void IMAPMessage::renumber(const size_t number) -{ +void IMAPMessage::renumber(const size_t number) { + m_num = number; } -void IMAPMessage::setExpunged() -{ +void IMAPMessage::setExpunged() { + m_expunged = true; } diff --git a/src/vmime/net/imap/IMAPMessage.hpp b/src/vmime/net/imap/IMAPMessage.hpp index 48722127..60875e8c 100644 --- a/src/vmime/net/imap/IMAPMessage.hpp +++ b/src/vmime/net/imap/IMAPMessage.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,9 +47,8 @@ class IMAPFolder; /** IMAP message implementation. */ +class VMIME_EXPORT IMAPMessage : public message { -class VMIME_EXPORT IMAPMessage : public message -{ private: friend class IMAPFolder; @@ -92,18 +91,22 @@ public: int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); - void extract - (utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, const size_t length = -1, - const bool peek = false) const; + void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; - void extractPart - (const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, const size_t length = -1, - const bool peek = false) const; + void extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; void fetchPartHeader(const shared_ptr & p); @@ -144,7 +147,11 @@ private: * @param str structure for which to construct part * @param level current nesting level (0 is root) */ - void constructParsedMessage(const shared_ptr & parentPart, const shared_ptr & str, int level = 0); + void constructParsedMessage( + const shared_ptr & parentPart, + const shared_ptr & str, + int level = 0 + ); enum ExtractFlags @@ -154,12 +161,14 @@ private: EXTRACT_PEEK = 0x10 }; - size_t extractImpl - (const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress, - const size_t start, const size_t length, - const int extractFlags) const; + size_t extractImpl( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const int extractFlags + ) const; shared_ptr
getOrCreateHeader(); diff --git a/src/vmime/net/imap/IMAPMessagePart.cpp b/src/vmime/net/imap/IMAPMessagePart.cpp index 6f3e7167..b76457fb 100644 --- a/src/vmime/net/imap/IMAPMessagePart.cpp +++ b/src/vmime/net/imap/IMAPMessagePart.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,129 +36,159 @@ namespace net { namespace imap { -IMAPMessagePart::IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_mpart* mpart) - : m_parent(parent), m_header(null), m_number(number), m_size(0) -{ - m_mediaType = vmime::mediaType - ("multipart", mpart->media_subtype()->value()); +IMAPMessagePart::IMAPMessagePart( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body_type_mpart* mpart +) + : m_parent(parent), + m_header(null), + m_number(number), + m_size(0) { + + m_mediaType = vmime::mediaType( + "multipart", + mpart->media_subtype()->value() + ); } -IMAPMessagePart::IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_1part* part) - : m_parent(parent), m_header(null), m_number(number), m_size(0) -{ - if (part->body_type_text()) - { - m_mediaType = vmime::mediaType - ("text", part->body_type_text()-> - media_text()->media_subtype()->value()); +IMAPMessagePart::IMAPMessagePart( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body_type_1part* part +) + : m_parent(parent), + m_header(null), + m_number(number), + m_size(0) { + + if (part->body_type_text()) { + + m_mediaType = vmime::mediaType( + "text", + part->body_type_text()->media_text()->media_subtype()->value() + ); m_size = part->body_type_text()->body_fields()->body_fld_octets()->value(); - } - else if (part->body_type_msg()) - { - m_mediaType = vmime::mediaType - ("message", part->body_type_msg()-> - media_message()->media_subtype()->value()); - } - else - { - m_mediaType = vmime::mediaType - (part->body_type_basic()->media_basic()->media_type()->value(), - part->body_type_basic()->media_basic()->media_subtype()->value()); + + } else if (part->body_type_msg()) { + + m_mediaType = vmime::mediaType( + "message", + part->body_type_msg()->media_message()->media_subtype()->value() + ); + + } else { + + m_mediaType = vmime::mediaType( + part->body_type_basic()->media_basic()->media_type()->value(), + part->body_type_basic()->media_basic()->media_subtype()->value() + ); m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value(); - if (const auto pparam = part->body_type_basic()->body_fields()->body_fld_param()) - for (const auto& param : pparam->items()) - if (param->string1()->value() == "NAME") + if (const auto pparam = part->body_type_basic()->body_fields()->body_fld_param()) { + for (const auto& param : pparam->items()) { + if (param->string1()->value() == "NAME") { m_name = param->string2()->value(); + } + } + } } m_structure = null; } -shared_ptr IMAPMessagePart::getStructure() const -{ - if (m_structure != NULL) +shared_ptr IMAPMessagePart::getStructure() const { + + if (m_structure) { return m_structure; - else + } else { return IMAPMessageStructure::emptyStructure(); + } } -shared_ptr IMAPMessagePart::getStructure() -{ - if (m_structure != NULL) +shared_ptr IMAPMessagePart::getStructure() { + + if (m_structure) { return m_structure; - else + } else { return IMAPMessageStructure::emptyStructure(); + } } -shared_ptr IMAPMessagePart::getParent() const -{ +shared_ptr IMAPMessagePart::getParent() const { + return m_parent.lock(); } -const mediaType& IMAPMessagePart::getType() const -{ +const mediaType& IMAPMessagePart::getType() const { + return m_mediaType; } -size_t IMAPMessagePart::getSize() const -{ +size_t IMAPMessagePart::getSize() const { + return m_size; } -size_t IMAPMessagePart::getNumber() const -{ +size_t IMAPMessagePart::getNumber() const { + return m_number; } -string IMAPMessagePart::getName() const -{ + +string IMAPMessagePart::getName() const { + return m_name; } -shared_ptr IMAPMessagePart::getHeader() const -{ - if (m_header == NULL) +shared_ptr IMAPMessagePart::getHeader() const { + + if (!m_header) { throw exceptions::unfetched_object(); - else + } else { return m_header; + } } // static -shared_ptr IMAPMessagePart::create - (const shared_ptr & parent, const size_t number, const IMAPParser::body* body) -{ - if (body->body_type_mpart()) - { +shared_ptr IMAPMessagePart::create( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body* body +) { + + if (body->body_type_mpart()) { + shared_ptr part = make_shared (parent, number, body->body_type_mpart()); part->m_structure = make_shared (part, body->body_type_mpart()->list()); return part; - } - else - { + + } else { + return make_shared (parent, number, body->body_type_1part()); } } -header& IMAPMessagePart::getOrCreateHeader() -{ - if (m_header != NULL) +header& IMAPMessagePart::getOrCreateHeader() { + + if (m_header) { return *m_header; - else + } else { return *(m_header = make_shared
()); + } } diff --git a/src/vmime/net/imap/IMAPMessagePart.hpp b/src/vmime/net/imap/IMAPMessagePart.hpp index d095c12f..4a636dd8 100644 --- a/src/vmime/net/imap/IMAPMessagePart.hpp +++ b/src/vmime/net/imap/IMAPMessagePart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,12 +44,21 @@ namespace imap { class IMAPMessageStructure; -class VMIME_EXPORT IMAPMessagePart : public messagePart -{ +class VMIME_EXPORT IMAPMessagePart : public messagePart { + public: - IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_mpart* mpart); - IMAPMessagePart(const shared_ptr & parent, const size_t number, const IMAPParser::body_type_1part* part); + IMAPMessagePart( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body_type_mpart* mpart + ); + + IMAPMessagePart( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body_type_1part* part + ); shared_ptr getStructure() const; shared_ptr getStructure(); @@ -64,8 +73,11 @@ public: shared_ptr getHeader() const; - static shared_ptr create - (const shared_ptr & parent, const size_t number, const IMAPParser::body* body); + static shared_ptr create( + const shared_ptr & parent, + const size_t number, + const IMAPParser::body* body + ); header& getOrCreateHeader(); diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp index 0917d0f7..d9cc07d9 100644 --- a/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,35 +42,44 @@ namespace net { namespace imap { -IMAPMessagePartContentHandler::IMAPMessagePartContentHandler - (const shared_ptr & msg, const shared_ptr & part, const vmime::encoding& encoding) - : m_message(msg), m_part(part), m_encoding(encoding) -{ +IMAPMessagePartContentHandler::IMAPMessagePartContentHandler( + const shared_ptr & msg, + const shared_ptr & part, + const vmime::encoding& encoding +) + : m_message(msg), + m_part(part), + m_encoding(encoding) { + } -shared_ptr IMAPMessagePartContentHandler::clone() const -{ - return make_shared - (m_message.lock(), m_part.lock(), m_encoding); +shared_ptr IMAPMessagePartContentHandler::clone() const { + + return make_shared ( + m_message.lock(), m_part.lock(), m_encoding + ); } -void IMAPMessagePartContentHandler::generate - (utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength) const -{ +void IMAPMessagePartContentHandler::generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength +) const { + shared_ptr msg = m_message.lock(); shared_ptr part = m_part.lock(); // Data is already encoded - if (isEncoded()) - { + if (isEncoded()) { + // The data is already encoded but the encoding specified for // the generation is different from the current one. We need // to re-encode data: decode from input buffer to temporary // buffer, and then re-encode to output stream... - if (m_encoding != enc) - { + if (m_encoding != enc) { + // Extract part contents to temporary buffer std::ostringstream oss; utility::outputStreamAdapter tmp(oss); @@ -95,16 +104,16 @@ void IMAPMessagePartContentHandler::generate theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT); theEncoder->encode(tempIn, os); - } + // No encoding to perform - else - { + } else { + msg->extractPart(part, os); } - } + // Need to encode data before - else - { + } else { + // Extract part contents to temporary buffer std::ostringstream oss; utility::outputStreamAdapter tmp(oss); @@ -123,20 +132,22 @@ void IMAPMessagePartContentHandler::generate } -void IMAPMessagePartContentHandler::extract - (utility::outputStream& os, utility::progressListener* progress) const -{ +void IMAPMessagePartContentHandler::extract( + utility::outputStream& os, + utility::progressListener* progress +) const { + shared_ptr msg = m_message.lock(); shared_ptr part = m_part.lock(); // No decoding to perform - if (!isEncoded()) - { + if (!isEncoded()) { + msg->extractImpl(part, os, progress, 0, -1, IMAPMessage::EXTRACT_BODY); - } + // Need to decode data - else - { + } else { + // Extract part contents to temporary buffer std::ostringstream oss; utility::outputStreamAdapter tmp(oss); @@ -153,9 +164,11 @@ void IMAPMessagePartContentHandler::extract } -void IMAPMessagePartContentHandler::extractRaw - (utility::outputStream& os, utility::progressListener* progress) const -{ +void IMAPMessagePartContentHandler::extractRaw( + utility::outputStream& os, + utility::progressListener* progress +) const { + shared_ptr msg = m_message.lock(); shared_ptr part = m_part.lock(); @@ -163,44 +176,44 @@ void IMAPMessagePartContentHandler::extractRaw } -size_t IMAPMessagePartContentHandler::getLength() const -{ +size_t IMAPMessagePartContentHandler::getLength() const { + return m_part.lock()->getSize(); } -bool IMAPMessagePartContentHandler::isEncoded() const -{ +bool IMAPMessagePartContentHandler::isEncoded() const { + return m_encoding != NO_ENCODING; } -const vmime::encoding& IMAPMessagePartContentHandler::getEncoding() const -{ +const vmime::encoding& IMAPMessagePartContentHandler::getEncoding() const { + return m_encoding; } -bool IMAPMessagePartContentHandler::isEmpty() const -{ +bool IMAPMessagePartContentHandler::isEmpty() const { + return getLength() == 0; } -bool IMAPMessagePartContentHandler::isBuffered() const -{ +bool IMAPMessagePartContentHandler::isBuffered() const { + return true; } -void IMAPMessagePartContentHandler::setContentTypeHint(const mediaType& type) -{ +void IMAPMessagePartContentHandler::setContentTypeHint(const mediaType& type) { + m_contentType = type; } -const mediaType IMAPMessagePartContentHandler::getContentTypeHint() const -{ +const mediaType IMAPMessagePartContentHandler::getContentTypeHint() const { + return m_contentType; } diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp index 8314fa95..17f53e34 100644 --- a/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,15 +40,23 @@ namespace net { namespace imap { -class VMIME_EXPORT IMAPMessagePartContentHandler : public contentHandler -{ +class VMIME_EXPORT IMAPMessagePartContentHandler : public contentHandler { + public: - IMAPMessagePartContentHandler(const shared_ptr & msg, const shared_ptr & part, const vmime::encoding& encoding); + IMAPMessagePartContentHandler( + const shared_ptr & msg, + const shared_ptr & part, + const vmime::encoding& encoding + ); shared_ptr clone() const; - void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + void generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength = lineLengthLimits::infinite + ) const; void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; diff --git a/src/vmime/net/imap/IMAPMessageStructure.cpp b/src/vmime/net/imap/IMAPMessageStructure.cpp index 1e6c1b32..0bc7e909 100644 --- a/src/vmime/net/imap/IMAPMessageStructure.cpp +++ b/src/vmime/net/imap/IMAPMessageStructure.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,50 +36,52 @@ namespace net { namespace imap { -IMAPMessageStructure::IMAPMessageStructure() -{ +IMAPMessageStructure::IMAPMessageStructure() { } -IMAPMessageStructure::IMAPMessageStructure(const IMAPParser::body* body) -{ +IMAPMessageStructure::IMAPMessageStructure(const IMAPParser::body* body) { + m_parts.push_back(IMAPMessagePart::create(null, 0, body)); } -IMAPMessageStructure::IMAPMessageStructure(const shared_ptr & parent, const std::vector & list) -{ +IMAPMessageStructure::IMAPMessageStructure( + const shared_ptr & parent, + const std::vector & list +) { + size_t number = 0; for (std::vector ::const_iterator - it = list.begin() ; it != list.end() ; ++it, ++number) - { + it = list.begin() ; it != list.end() ; ++it, ++number) { + m_parts.push_back(IMAPMessagePart::create(parent, number, *it)); } } -shared_ptr IMAPMessageStructure::getPartAt(const size_t x) const -{ +shared_ptr IMAPMessageStructure::getPartAt(const size_t x) const { + return m_parts[x]; } -shared_ptr IMAPMessageStructure::getPartAt(const size_t x) -{ +shared_ptr IMAPMessageStructure::getPartAt(const size_t x) { + return m_parts[x]; } -size_t IMAPMessageStructure::getPartCount() const -{ +size_t IMAPMessageStructure::getPartCount() const { + return m_parts.size(); } // static -shared_ptr IMAPMessageStructure::emptyStructure() -{ +shared_ptr IMAPMessageStructure::emptyStructure() { + static shared_ptr emptyStructure = make_shared (); return emptyStructure; } diff --git a/src/vmime/net/imap/IMAPMessageStructure.hpp b/src/vmime/net/imap/IMAPMessageStructure.hpp index f24e518c..5eafb04f 100644 --- a/src/vmime/net/imap/IMAPMessageStructure.hpp +++ b/src/vmime/net/imap/IMAPMessageStructure.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace imap { class IMAPMessagePart; -class VMIME_EXPORT IMAPMessageStructure : public messageStructure -{ +class VMIME_EXPORT IMAPMessageStructure : public messageStructure { + public: IMAPMessageStructure(); diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp index 33d091cc..74b5145f 100644 --- a/src/vmime/net/imap/IMAPParser.hpp +++ b/src/vmime/net/imap/IMAPParser.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -193,25 +193,34 @@ namespace imap { static int IMAPParserDebugResponse_level = 0; static std::vector IMAPParserDebugResponse_stack; - class IMAPParserDebugResponse - { + class IMAPParserDebugResponse { + public: - IMAPParserDebugResponse(const string& name, string& line, const size_t currentPos, const bool &result) - : m_name(name), m_line(line), m_pos(currentPos), m_result(result) - { + IMAPParserDebugResponse( + const string& name, + string& line, + const size_t currentPos, + const bool &result + ) + : m_name(name), + m_line(line), + m_pos(currentPos), + m_result(result) { + ++IMAPParserDebugResponse_level; IMAPParserDebugResponse_stack.push_back(name); - for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) + for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) { std::cout << " "; + } std::cout << "ENTER(" << m_name << "), pos=" << m_pos; std::cout << std::endl; for (std::vector ::iterator it = IMAPParserDebugResponse_stack.begin() ; - it != IMAPParserDebugResponse_stack.end() ; ++it) - { + it != IMAPParserDebugResponse_stack.end() ; ++it) { + std::cout << "> " << *it << " "; } @@ -219,16 +228,18 @@ namespace imap { std::cout << string(m_line.begin() + (m_pos < 30 ? 0U : m_pos - 30), m_line.begin() + std::min(m_line.length(), m_pos + 30)) << std::endl; - for (size_t i = (m_pos < 30 ? m_pos : (m_pos - (m_pos - 30))) ; i != 0 ; --i) + for (size_t i = (m_pos < 30 ? m_pos : (m_pos - (m_pos - 30))) ; i != 0 ; --i) { std::cout << " "; + } std::cout << "^" << std::endl; } - ~IMAPParserDebugResponse() - { - for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) + ~IMAPParserDebugResponse() { + + for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) { std::cout << " "; + } std::cout << "LEAVE(" << m_name << "), result="; std::cout << (m_result ? "TRUE" : "FALSE") << ", pos=" << m_pos; @@ -258,14 +269,18 @@ namespace imap { #endif -class VMIME_EXPORT IMAPParser : public object -{ +class VMIME_EXPORT IMAPParser : public object { + public: IMAPParser() - : m_tag(), m_socket(), m_progress(NULL), m_strict(false), - m_literalHandler(NULL), m_timeoutHandler() - { + : m_tag(), + m_socket(), + m_progress(NULL), + m_strict(false), + m_literalHandler(NULL), + m_timeoutHandler() { + } @@ -273,8 +288,8 @@ public: * * @param tag IMAP command tag */ - void setTag(const shared_ptr & tag) - { + void setTag(const shared_ptr & tag) { + m_tag = tag; } @@ -282,8 +297,8 @@ public: * * @return IMAP command tag */ - shared_ptr getTag() const - { + shared_ptr getTag() const { + return m_tag.lock(); } @@ -292,8 +307,8 @@ public: * * @param sok socket */ - void setSocket(const shared_ptr & sok) - { + void setSocket(const shared_ptr & sok) { + m_socket = sok; } @@ -301,8 +316,8 @@ public: * * @param toh timeout handler */ - void setTimeoutHandler(const shared_ptr & toh) - { + void setTimeoutHandler(const shared_ptr & toh) { + m_timeoutHandler = toh; } @@ -310,8 +325,8 @@ public: * * @param tr tracer */ - void setTracer(const shared_ptr & tr) - { + void setTracer(const shared_ptr & tr) { + m_tracer = tr; } @@ -321,8 +336,8 @@ public: * @param strict true to operate in strict mode, or false * to operate in default, relaxed mode */ - void setStrict(const bool strict) - { + void setStrict(const bool strict) { + m_strict = strict; } @@ -331,8 +346,8 @@ public: * * @return true if we are in strict mode, false otherwise */ - bool isStrict() const - { + bool isStrict() const { + return m_strict; } @@ -344,16 +359,16 @@ public: class component; - class literalHandler - { + class literalHandler { + public: virtual ~literalHandler() { } // Abstract target class - class target - { + class target { + protected: target(utility::progressListener* progress) : m_progress(progress) {} @@ -377,8 +392,8 @@ public: // Target: put in a string - class targetString : public target - { + class targetString : public target { + public: targetString(utility::progressListener* progress, vmime::string& str) @@ -388,14 +403,14 @@ public: vmime::string& string() { return (m_string); } - void putData(const vmime::string& chunk) - { + void putData(const vmime::string& chunk) { + m_string += chunk; m_bytesWritten += chunk.length(); } - size_t getBytesWritten() const - { + size_t getBytesWritten() const { + return m_bytesWritten; } @@ -407,25 +422,32 @@ public: // Target: redirect to an output stream - class targetStream : public target - { + class targetStream : public target { + public: - targetStream(utility::progressListener* progress, utility::outputStream& stream) - : target(progress), m_stream(stream), m_bytesWritten(0) { } + targetStream( + utility::progressListener* progress, + utility::outputStream& stream + ) + : target(progress), + m_stream(stream), + m_bytesWritten(0) { + + } const utility::outputStream& stream() const { return (m_stream); } utility::outputStream& stream() { return (m_stream); } - void putData(const string& chunk) - { + void putData(const string& chunk) { + m_stream.write(chunk.data(), chunk.length()); m_bytesWritten += chunk.length(); } - size_t getBytesWritten() const - { + size_t getBytesWritten() const { + return m_bytesWritten; } @@ -452,8 +474,8 @@ public: // Base class for a terminal or a non-terminal // - class component - { + class component { + public: component() { } @@ -461,8 +483,8 @@ public: virtual const string getComponentName() const = 0; - bool parse(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parse(IMAPParser& parser, string& line, size_t* currentPos) { + bool res = false; DEBUG_ENTER_COMPONENT(getComponentName(), res); res = parseImpl(parser, line, currentPos); @@ -472,12 +494,16 @@ public: virtual bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) = 0; - const string makeResponseLine(const string& comp, const string& line, - const size_t pos) - { + const string makeResponseLine( + const string& comp, + const string& line, + const size_t pos + ) { + #if DEBUG_RESPONSE - if (pos > line.length()) + if (pos > line.length()) { std::cout << "WARNING: component::makeResponseLine(): pos > line.length()" << std::endl; + } #endif string result(line.substr(0, pos)); @@ -491,19 +517,16 @@ public: #define COMPONENT_ALIAS(parent, name) \ - class name : public parent \ - { \ + class name : public parent { \ virtual const string getComponentName() const { return #name; } \ public: \ - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) \ - { \ + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { \ return parent::parseImpl(parser, line, currentPos); \ } \ } #define DECLARE_COMPONENT(name) \ - class name : public component \ - { \ + class name : public component { \ virtual const string getComponentName() const { return #name; } \ public: @@ -513,26 +536,23 @@ public: // template - class one_char : public component - { + class one_char : public component { + public: - const string getComponentName() const - { + const string getComponentName() const { + return string("one_char <") + C + ">"; } - bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) { + const size_t pos = *currentPos; - if (pos < line.length() && line[pos] == C) - { + if (pos < line.length() && line[pos] == C) { *currentPos = pos + 1; return true; - } - else - { + } else { return false; } } @@ -545,20 +565,18 @@ public: DECLARE_COMPONENT(SPACE) - bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) { + size_t pos = *currentPos; - while (pos < line.length() && (line[pos] == ' ' || line[pos] == '\t')) + while (pos < line.length() && (line[pos] == ' ' || line[pos] == '\t')) { ++pos; + } - if (pos > *currentPos) - { + if (pos > *currentPos) { *currentPos = pos; return true; - } - else - { + } else { return false; } } @@ -573,20 +591,20 @@ public: DECLARE_COMPONENT(CRLF) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_TRY_CHECK(SPACE); if (pos + 1 < line.length() && - line[pos] == 0x0d && line[pos + 1] == 0x0a) - { + line[pos] == 0x0d && line[pos + 1] == 0x0a) { + *currentPos = pos + 2; return true; - } - else - { + + } else { + return false; } } @@ -607,8 +625,8 @@ public: DECLARE_COMPONENT(xtag) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; bool end = false; @@ -616,46 +634,42 @@ public: string tagString; tagString.reserve(10); - while (!end && pos < line.length()) - { + while (!end && pos < line.length()) { + const unsigned char c = line[pos]; - switch (c) - { - case '+': - case '(': - case ')': - case '{': - case 0x20: // SPACE - case '%': // list_wildcards - case '*': // list_wildcards - case '"': // quoted_specials - case '\\': // quoted_specials + switch (c) { - end = true; - break; + case '+': + case '(': + case ')': + case '{': + case 0x20: // SPACE + case '%': // list_wildcards + case '*': // list_wildcards + case '"': // quoted_specials + case '\\': // quoted_specials - default: - - if (c <= 0x1f || c >= 0x7f) end = true; - else - { - tagString += c; - ++pos; - } + break; - break; + default: + + if (c <= 0x1f || c >= 0x7f) { + end = true; + } else { + tagString += c; + ++pos; + } + + break; } } - if (tagString == string(*parser.getTag())) - { + if (tagString == string(*parser.getTag())) { *currentPos = pos; return true; - } - else - { + } else { // Invalid tag return false; } @@ -675,41 +689,36 @@ public: DECLARE_COMPONENT(number) number(const bool nonZero = false) - : m_nonZero(nonZero), m_value(0) - { + : m_nonZero(nonZero), + m_value(0) { + } - bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) { + size_t pos = *currentPos; bool valid = true; unsigned int val = 0; - while (valid && pos < line.length()) - { + while (valid && pos < line.length()) { + const char c = line[pos]; - if (c >= '0' && c <= '9') - { + if (c >= '0' && c <= '9') { val = (val * 10) + (c - '0'); ++pos; - } - else - { + } else { valid = false; } } // Check for non-null length (and for non-zero number) - if (!(m_nonZero && val == 0) && pos != *currentPos) - { + if (!(m_nonZero && val == 0) && pos != *currentPos) { m_value = val; *currentPos = pos; return true; - } - else - { + } else { return false; } } @@ -730,12 +739,13 @@ public: // ;; (0 < n < 4,294,967,296) // - class nz_number : public number - { + class nz_number : public number { + public: - nz_number() : number(true) - { + nz_number() + : number(true) { + } }; @@ -745,12 +755,13 @@ public: // ;; Strictly ascending // - class uniqueid : public nz_number - { + class uniqueid : public nz_number { + public: - uniqueid() : nz_number() - { + uniqueid() + : nz_number() { + } }; @@ -763,18 +774,19 @@ public: DECLARE_COMPONENT(uid_range) uid_range() - : m_uniqueid1(NULL), m_uniqueid2(NULL) - { + : m_uniqueid1(NULL), + m_uniqueid2(NULL) { + } - ~uid_range() - { + ~uid_range() { + delete m_uniqueid1; delete m_uniqueid2; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(uniqueid, m_uniqueid1); @@ -805,28 +817,32 @@ public: DECLARE_COMPONENT(uid_set) uid_set() - : m_uniqueid(NULL), m_uid_range(NULL), m_next_uid_set(NULL) - { + : m_uniqueid(NULL), + m_uid_range(NULL), + m_next_uid_set(NULL) { + } - ~uid_set() - { + ~uid_set() { + delete m_uniqueid; delete m_uid_range; delete m_next_uid_set; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // We have either a 'uid_range' or a 'uniqueid' - if (!VIMAP_PARSER_TRY_GET(IMAPParser::uid_range, m_uid_range)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::uid_range, m_uid_range)) { VIMAP_PARSER_GET(IMAPParser::uniqueid, m_uniqueid); + } // And maybe another 'uid-set' following - if (VIMAP_PARSER_TRY_CHECK(one_char <','>)) + if (VIMAP_PARSER_TRY_CHECK(one_char <','>)) { VIMAP_PARSER_GET(IMAPParser::uid_set, m_next_uid_set); + } *currentPos = pos; @@ -859,56 +875,50 @@ public: DECLARE_COMPONENT(text) text(bool allow8bits = false, const char except = 0) - : m_allow8bits(allow8bits), m_except(except) - { + : m_allow8bits(allow8bits), m_except(except) { } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; size_t len = 0; - if (m_allow8bits || !parser.isStrict()) - { + if (m_allow8bits || !parser.isStrict()) { + const unsigned char except = m_except; - for (bool end = false ; !end && pos < line.length() ; ) - { + for (bool end = false ; !end && pos < line.length() ; ) { + const unsigned char c = line[pos]; - if (c == 0x00 || c == 0x0d || c == 0x0a || c == except) - { + if (c == 0x00 || c == 0x0d || c == 0x0a || c == except) { end = true; - } - else - { + } else { ++pos; ++len; } } - } - else - { + + } else { + const unsigned char except = m_except; - for (bool end = false ; !end && pos < line.length() ; ) - { + for (bool end = false ; !end && pos < line.length() ; ) { + const unsigned char c = line[pos]; - if (c < 0x01 || c > 0x7f || c == 0x0d || c == 0x0a || c == except) - { + if (c < 0x01 || c > 0x7f || c == 0x0d || c == 0x0a || c == except) { end = true; - } - else - { + } else { ++pos; ++len; } } } - if (len == 0) + if (len == 0) { VIMAP_PARSER_FAIL(); + } m_value.resize(len); std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); @@ -930,34 +940,34 @@ public: }; - class text8 : public text - { + class text8 : public text { + public: - text8() : text(true) - { + text8() : text(true) { + } }; template - class text_except : public text - { + class text_except : public text { + public: - text_except() : text(false, C) - { + text_except() : text(false, C) { + } }; template - class text8_except : public text - { + class text8_except : public text { + public: - text8_except() : text(true, C) - { + text8_except() : text(true, C) { + } }; @@ -971,27 +981,27 @@ public: DECLARE_COMPONENT(QUOTED_CHAR) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; const unsigned char c = static_cast (pos < line.length() ? line[pos] : 0); if (c >= 0x01 && c <= 0x7f && // 0x01 - 0x7f c != '"' && c != '\\' && // quoted_specials - c != '\r' && c != '\n') // CR and LF - { + c != '\r' && c != '\n') { // CR and LF + m_value = c; *currentPos = pos + 1; - } - else if (c == '\\' && pos + 1 < line.length() && - (line[pos + 1] == '"' || line[pos + 1] == '\\')) - { + + } else if (c == '\\' && pos + 1 < line.length() && + (line[pos + 1] == '"' || line[pos + 1] == '\\')) { + m_value = line[pos + 1]; *currentPos = pos + 2; - } - else - { + + } else { + VIMAP_PARSER_FAIL(); } @@ -1018,24 +1028,23 @@ public: DECLARE_COMPONENT(quoted_text) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; size_t len = 0; bool valid = false; m_value.reserve(line.length() - pos); - for (bool end = false, quoted = false ; !end && pos < line.length() ; ) - { + for (bool end = false, quoted = false ; !end && pos < line.length() ; ) { + const unsigned char c = line[pos]; - if (quoted) - { - if (c == '"' || c == '\\') + if (quoted) { + + if (c == '"' || c == '\\') { m_value += c; - else - { + } else { m_value += '\\'; m_value += c; } @@ -1044,39 +1053,40 @@ public: ++pos; ++len; - } - else - { - if (c == '\\') - { + + } else { + + if (c == '\\') { + quoted = true; ++pos; ++len; - } - else if (c == '"') - { + + } else if (c == '"') { + valid = true; end = true; - } - else if (c >= 0x01 && c <= 0x7f && // CHAR - c != 0x0a && c != 0x0d) // CR and LF - { + + } else if (c >= 0x01 && c <= 0x7f && // CHAR + c != 0x0a && c != 0x0d) { // CR and LF + m_value += c; ++pos; ++len; - } - else - { + + } else { + valid = false; end = true; } } } - if (!valid) + if (!valid) { VIMAP_PARSER_FAIL(); + } *currentPos = pos; @@ -1099,8 +1109,8 @@ public: DECLARE_COMPONENT(NIL) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK_WITHARG(special_atom, "nil"); @@ -1128,74 +1138,79 @@ public: DECLARE_COMPONENT(xstring) - xstring(const bool canBeNIL = false, component* comp = NULL, const int data = 0) - : m_canBeNIL(canBeNIL), m_isNIL(true), m_component(comp), m_data(data) - { + xstring( + const bool canBeNIL = false, + component* comp = NULL, + const int data = 0 + ) + : m_canBeNIL(canBeNIL), + m_isNIL(true), + m_component(comp), + m_data(data) { + } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; if (m_canBeNIL && - VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "nil")) - { + VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "nil")) { + // NIL m_isNIL = true; - } - else - { + + } else { + pos = *currentPos; m_isNIL = false; // quoted ::= <"> *QUOTED_CHAR <"> - if (VIMAP_PARSER_TRY_CHECK(one_char <'"'>)) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'"'>)) { + shared_ptr text; VIMAP_PARSER_GET_PTR(quoted_text, text); VIMAP_PARSER_CHECK(one_char <'"'>); - if (parser.m_literalHandler != NULL) - { + if (parser.m_literalHandler != NULL) { + shared_ptr target = parser.m_literalHandler->targetFor(*m_component, m_data); - if (target != NULL) - { + if (target != NULL) { + m_value = "[literal-handler]"; const size_t length = text->value().length(); utility::progressListener* progress = target->progressListener(); - if (progress) - { + if (progress) { progress->start(length); } target->putData(text->value()); - if (progress) - { + if (progress) { progress->progress(length, length); progress->stop(length); } - } - else - { + + } else { + m_value = text->value(); } - } - else - { + + } else { + m_value = text->value(); } DEBUG_FOUND("string[quoted]", ""); - } + // literal ::= "{" number "}" CRLF *CHAR8 - else - { + } else { + VIMAP_PARSER_CHECK(one_char <'{'>); shared_ptr num; @@ -1208,27 +1223,27 @@ public: VIMAP_PARSER_CHECK(CRLF); - if (parser.m_literalHandler != NULL) - { + if (parser.m_literalHandler != NULL) { + shared_ptr target = parser.m_literalHandler->targetFor(*m_component, m_data); - if (target != NULL) - { + if (target != NULL) { + m_value = "[literal-handler]"; parser.m_progress = target->progressListener(); parser.readLiteral(*target, length); parser.m_progress = NULL; - } - else - { + + } else { + literalHandler::targetString target(NULL, m_value); parser.readLiteral(target, length); } - } - else - { + + } else { + literalHandler::targetString target(NULL, m_value); parser.readLiteral(target, length); } @@ -1266,18 +1281,18 @@ public: // nstring ::= string / nil // - class nstring : public xstring - { + class nstring : public xstring { + public: - const string getComponentName() const - { + const string getComponentName() const { + return "nstring"; } nstring(component* comp = NULL, const int data = 0) - : xstring(true, comp, data) - { + : xstring(true, comp, data) { + } }; @@ -1288,19 +1303,16 @@ public: DECLARE_COMPONENT(astring) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; shared_ptr str; VIMAP_PARSER_TRY_GET_PTR(xstring, str); - if (str) - { + if (str) { m_value = str->value(); - } - else - { + } else { shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); m_value = at->value(); @@ -1335,53 +1347,52 @@ public: DECLARE_COMPONENT(atom) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; size_t len = 0; - for (bool end = false ; !end && pos < line.length() ; ) - { + for (bool end = false ; !end && pos < line.length() ; ) { + const unsigned char c = line[pos]; - switch (c) - { - case '(': - case ')': - case '{': - case 0x20: // SPACE - case '%': // list_wildcards - case '*': // list_wildcards - case '"': // quoted_specials - case '\\': // quoted_specials + switch (c) { - case '[': - case ']': // for "special_atom" + case '(': + case ')': + case '{': + case 0x20: // SPACE + case '%': // list_wildcards + case '*': // list_wildcards + case '"': // quoted_specials + case '\\': // quoted_specials - end = true; - break; + case '[': + case ']': // for "special_atom" - default: - - if (c <= 0x1f || c >= 0x7f) end = true; - else - { - ++pos; - ++len; + break; + + default: + + if (c <= 0x1f || c >= 0x7f) { + end = true; + } else { + ++pos; + ++len; + } } - } } - if (len != 0) - { + if (len != 0) { + m_value.resize(len); std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); *currentPos = pos; - } - else - { + + } else { + VIMAP_PARSER_FAIL(); } @@ -1407,42 +1418,44 @@ public: // accept these strings in a case-insensitive fashion. " // - class special_atom : public atom - { + class special_atom : public atom { + public: - const std::string getComponentName() const - { + const std::string getComponentName() const { + return string("special_atom <") + m_string + ">"; } special_atom(const char* str) - : m_string(str) // 'string' must be in lower-case - { + : m_string(str) { // 'string' must be in lower-case + } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!atom::parseImpl(parser, line, &pos)) + if (!atom::parseImpl(parser, line, &pos)) { return false; + } const char* cmp = value().c_str(); const char* with = m_string; bool ok = true; - while (ok && *cmp && *with) - { + while (ok && *cmp && *with) { + ok = (std::tolower(*cmp, std::locale()) == *with); ++cmp; ++with; } - if (!ok || *cmp || *with) + if (!ok || *cmp || *with) { VIMAP_PARSER_FAIL(); + } *currentPos = pos; @@ -1462,8 +1475,8 @@ public: DECLARE_COMPONENT(text_mime2) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; shared_ptr theCharset, theEncoding; @@ -1490,28 +1503,28 @@ public: // Decode text scoped_ptr theEncoder; - if (theEncoding->value()[0] == 'q' || theEncoding->value()[0] == 'Q') - { + if (theEncoding->value()[0] == 'q' || theEncoding->value()[0] == 'Q') { + // Quoted-printable theEncoder.reset(new utility::encoder::qpEncoder()); theEncoder->getProperties()["rfc2047"] = true; - } - else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B') - { + + } else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B') { + // Base64 theEncoder.reset(new utility::encoder::b64Encoder()); } - if (theEncoder.get()) - { + if (theEncoder.get()) { + utility::inputStreamStringAdapter in(theText->value()); utility::outputStreamStringAdapter out(m_value); theEncoder->decode(in, out); - } + // No decoder available - else - { + } else { + m_value = theText->value(); } @@ -1540,26 +1553,27 @@ public: DECLARE_COMPONENT(seq_number) seq_number() - : m_number(NULL), m_star(false) - { + : m_number(NULL), + m_star(false) { + } - ~seq_number() - { + ~seq_number() { + delete m_number; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'*'> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'*'> )) { + m_star = true; m_number = NULL; - } - else - { + + } else { + m_star = false; VIMAP_PARSER_GET(IMAPParser::number, m_number); } @@ -1590,18 +1604,19 @@ public: DECLARE_COMPONENT(seq_range) seq_range() - : m_first(NULL), m_last(NULL) - { + : m_first(NULL), + m_last(NULL) { + } - ~seq_range() - { + ~seq_range() { + delete m_first; delete m_last; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(seq_number, m_first); @@ -1638,26 +1653,30 @@ public: DECLARE_COMPONENT(sequence_set) sequence_set() - : m_number(NULL), m_range(NULL), m_nextSet(NULL) - { + : m_number(NULL), + m_range(NULL), + m_nextSet(NULL) { + } - ~sequence_set() - { + ~sequence_set() { + delete m_number; delete m_range; delete m_nextSet; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!VIMAP_PARSER_TRY_GET(IMAPParser::seq_range, m_range)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::seq_range, m_range)) { VIMAP_PARSER_GET(IMAPParser::seq_number, m_number); + } - if (VIMAP_PARSER_TRY_CHECK(one_char <','> )) + if (VIMAP_PARSER_TRY_CHECK(one_char <','> )) { VIMAP_PARSER_GET(sequence_set, m_nextSet); + } *currentPos = pos; @@ -1686,28 +1705,25 @@ public: DECLARE_COMPONENT(mod_sequence_value) mod_sequence_value() - : m_value(0) - { + : m_value(0) { + } - bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& /* parser */, string& line, size_t* currentPos) { + size_t pos = *currentPos; bool valid = true; vmime_uint64 val = 0; - while (valid && pos < line.length()) - { + while (valid && pos < line.length()) { + const char c = line[pos]; - if (c >= '0' && c <= '9') - { + if (c >= '0' && c <= '9') { val = (val * 10) + (c - '0'); ++pos; - } - else - { + } else { valid = false; } } @@ -1747,51 +1763,51 @@ public: DECLARE_COMPONENT(flag) flag() - : m_type(UNKNOWN), m_flag_keyword(NULL) - { + : m_type(UNKNOWN), + m_flag_keyword(NULL) { + } - ~flag() - { - delete (m_flag_keyword); + ~flag() { + + delete m_flag_keyword; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'\\'> )) - { - if (VIMAP_PARSER_TRY_CHECK(one_char <'*'> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'\\'> )) { + + if (VIMAP_PARSER_TRY_CHECK(one_char <'*'> )) { + m_type = STAR; - } - else - { + + } else { + shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); const string name = utility::stringUtils::toLower(at->value()); - if (name == "answered") + if (name == "answered") { m_type = ANSWERED; - else if (name == "flagged") + } else if (name == "flagged") { m_type = FLAGGED; - else if (name == "deleted") + } else if (name == "deleted") { m_type = DELETED; - else if (name == "seen") + } else if (name == "seen") { m_type = SEEN; - else if (name == "draft") + } else if (name == "draft") { m_type = DRAFT; - else - { + } else { m_type = UNKNOWN; m_name = name; } } - } - else - { + + } else { + m_type = KEYWORD_OR_EXTENSION; VIMAP_PARSER_GET(atom, m_flag_keyword); } @@ -1802,8 +1818,7 @@ public: } - enum Type - { + enum Type { UNKNOWN, ANSWERED, FLAGGED, @@ -1836,23 +1851,22 @@ public: DECLARE_COMPONENT(flag_list) - ~flag_list() - { + ~flag_list() { + for (std::vector ::iterator it = m_flags.begin() ; - it != m_flags.end() ; ++it) - { - delete (*it); + it != m_flags.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_GET_PUSHBACK(flag, m_flags); VIMAP_PARSER_TRY_CHECK(SPACE); } @@ -1882,17 +1896,17 @@ public: DECLARE_COMPONENT(mailbox) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "inbox")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "inbox")) { + m_type = INBOX; m_name = "INBOX"; - } - else - { + + } else { + m_type = OTHER; shared_ptr astr; @@ -1906,8 +1920,7 @@ public: } - enum Type - { + enum Type { INBOX, OTHER }; @@ -1931,109 +1944,121 @@ public: DECLARE_COMPONENT(mailbox_flag) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'\\'> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'\\'> )) { + shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); const string name = utility::stringUtils::toLower(at->value()); m_type = UNKNOWN; // default - switch (name[0]) - { - case 'a': + switch (name[0]) { - if (name == "all") - m_type = SPECIALUSE_ALL; - else if (name == "archive") - m_type = SPECIALUSE_ARCHIVE; + case 'a': - break; + if (name == "all") { + m_type = SPECIALUSE_ALL; + } else if (name == "archive") { + m_type = SPECIALUSE_ARCHIVE; + } - case 'd': + break; - if (name == "drafts") - m_type = SPECIALUSE_DRAFTS; + case 'd': - break; + if (name == "drafts") { + m_type = SPECIALUSE_DRAFTS; + } - case 'f': + break; - if (name == "flagged") - m_type = SPECIALUSE_FLAGGED; + case 'f': - break; + if (name == "flagged") { + m_type = SPECIALUSE_FLAGGED; + } - case 'h': + break; - if (name == "haschildren") - m_type = HASCHILDREN; - else if (name == "hasnochildren") - m_type = HASNOCHILDREN; + case 'h': - break; + if (name == "haschildren") { + m_type = HASCHILDREN; + } else if (name == "hasnochildren") { + m_type = HASNOCHILDREN; + } - case 'i': + break; - if (name == "important") - m_type = SPECIALUSE_IMPORTANT; + case 'i': - break; + if (name == "important") { + m_type = SPECIALUSE_IMPORTANT; + } - case 'j': + break; - if (name == "junk") - m_type = SPECIALUSE_JUNK; + case 'j': - break; + if (name == "junk") { + m_type = SPECIALUSE_JUNK; + } - case 'm': + break; - if (name == "marked") - m_type = MARKED; + case 'm': - break; + if (name == "marked") { + m_type = MARKED; + } - case 'n': + break; - if (name == "noinferiors") - m_type = NOINFERIORS; - else if (name == "noselect") - m_type = NOSELECT; + case 'n': - break; + if (name == "noinferiors") { + m_type = NOINFERIORS; + } else if (name == "noselect") { + m_type = NOSELECT; + } - case 's': + break; - if (name == "sent") - m_type = SPECIALUSE_SENT; + case 's': - break; + if (name == "sent") { + m_type = SPECIALUSE_SENT; + } - case 't': + break; - if (name == "trash") - m_type = SPECIALUSE_TRASH; + case 't': - break; + if (name == "trash") { + m_type = SPECIALUSE_TRASH; + } - case 'u': + break; - if (name == "unmarked") - m_type = UNMARKED; + case 'u': - break; + if (name == "unmarked") { + m_type = UNMARKED; + } + + break; } - if (m_type == UNKNOWN) + if (m_type == UNKNOWN) { m_name = "\\" + name; - } - else - { + } + + } else { + shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); const string name = utility::stringUtils::toLower(at->value()); @@ -2048,8 +2073,7 @@ public: } - enum Type - { + enum Type { // RFC-3348 - Child Mailbox Extension HASCHILDREN, HASNOCHILDREN, @@ -2090,23 +2114,22 @@ public: DECLARE_COMPONENT(mailbox_flag_list) - ~mailbox_flag_list() - { + ~mailbox_flag_list() { + for (std::vector ::iterator it = m_flags.begin() ; - it != m_flags.end() ; ++it) - { - delete (*it); + it != m_flags.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_GET_PUSHBACK(mailbox_flag, m_flags); VIMAP_PARSER_TRY_CHECK(SPACE); } @@ -2135,26 +2158,26 @@ public: mailbox_list() : m_mailbox_flag_list(NULL), - m_mailbox(NULL), m_quoted_char('\0') - { + m_mailbox(NULL), m_quoted_char('\0') { + } - ~mailbox_list() - { - delete (m_mailbox_flag_list); - delete (m_mailbox); + ~mailbox_list() { + + delete m_mailbox_flag_list; + delete m_mailbox; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::mailbox_flag_list, m_mailbox_flag_list); VIMAP_PARSER_CHECK(SPACE); - if (!VIMAP_PARSER_TRY_CHECK(NIL)) - { + if (!VIMAP_PARSER_TRY_CHECK(NIL)) { + VIMAP_PARSER_CHECK(one_char <'"'> ); shared_ptr qc; @@ -2194,29 +2217,29 @@ public: DECLARE_COMPONENT(auth_type) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); m_name = utility::stringUtils::toLower(at->value()); - if (m_name == "kerberos_v4") + if (m_name == "kerberos_v4") { m_type = KERBEROS_V4; - else if (m_name == "gssapi") + } else if (m_name == "gssapi") { m_type = GSSAPI; - else if (m_name == "skey") + } else if (m_name == "skey") { m_type = SKEY; - else + } else { m_type = UNKNOWN; + } return true; } - enum Type - { + enum Type { UNKNOWN, // RFC 1731 - IMAP4 Authentication Mechanisms @@ -2255,47 +2278,38 @@ public: DECLARE_COMPONENT(status_att_val) status_att_val() - : m_value(NULL) - { + : m_value(NULL) { + } - ~status_att_val() - { + ~status_att_val() { + delete m_value; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // "HIGHESTMODSEQ" SP mod-sequence-valzer - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "highestmodseq")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "highestmodseq")) { + m_type = HIGHESTMODSEQ; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::mod_sequence_value, m_value); - } - else - { - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "messages")) - { + + } else { + + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "messages")) { m_type = MESSAGES; - } - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "recent")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "recent")) { m_type = RECENT; - } - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnext")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnext")) { m_type = UIDNEXT; - } - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidvalidity")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidvalidity")) { m_type = UIDVALIDITY; - } - else - { + } else { VIMAP_PARSER_CHECK_WITHARG(special_atom, "unseen"); m_type = UNSEEN; } @@ -2310,8 +2324,7 @@ public: } - enum Type - { + enum Type { // Extensions HIGHESTMODSEQ, @@ -2332,13 +2345,11 @@ public: Type type() const { return (m_type); } - const IMAPParser::number* value_as_number() const - { + const IMAPParser::number* value_as_number() const { return dynamic_cast (m_value); } - const IMAPParser::mod_sequence_value* value_as_mod_sequence_value() const - { + const IMAPParser::mod_sequence_value* value_as_mod_sequence_value() const { return dynamic_cast (m_value); } }; @@ -2348,23 +2359,24 @@ public: DECLARE_COMPONENT(status_att_list) - ~status_att_list() - { + ~status_att_list() { + for (std::vector ::iterator it = m_values.begin() ; - it != m_values.end() ; ++it) - { + it != m_values.end() ; ++it) { + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET_PUSHBACK(IMAPParser::status_att_val, m_values); - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET_PUSHBACK(IMAPParser::status_att_val, m_values); + } *currentPos = pos; @@ -2390,18 +2402,19 @@ public: DECLARE_COMPONENT(capability) capability() - : m_auth_type(NULL), m_atom(NULL) - { + : m_auth_type(NULL), + m_atom(NULL) { + } - ~capability() - { - delete (m_auth_type); - delete (m_atom); + ~capability() { + + delete m_auth_type; + delete m_atom; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::atom, m_atom); @@ -2413,8 +2426,8 @@ public: (str[1] == 'u' || str[1] == 'U') && (str[2] == 't' || str[2] == 'T') && (str[3] == 'h' || str[3] == 'H') && - (str[4] == '=')) - { + (str[4] == '=')) { + size_t pos = 5; m_auth_type = parser.get (value, &pos); @@ -2449,36 +2462,34 @@ public: DECLARE_COMPONENT(capability_data) - ~capability_data() - { + ~capability_data() { + for (std::vector ::iterator it = m_capabilities.begin() ; - it != m_capabilities.end() ; ++it) - { - delete (*it); + it != m_capabilities.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK_WITHARG(special_atom, "capability"); - while (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { + capability* cap; - if (parser.isStrict() || m_capabilities.empty()) - { + if (parser.isStrict() || m_capabilities.empty()) { VIMAP_PARSER_GET(capability, cap); - } - else - { + } else { VIMAP_PARSER_TRY_GET(capability, cap); // allow SPACE at end of line (Apple iCloud IMAP server) } - if (!cap) + if (!cap) { break; + } m_capabilities.push_back(cap); } @@ -2524,8 +2535,8 @@ public: DECLARE_COMPONENT(date_time) - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // <"> date_day_fixed "-" date_month "-" date_year @@ -2566,8 +2577,9 @@ public: // ("+" / "-") 4digit int sign = 1; - if (!(VIMAP_PARSER_TRY_CHECK(one_char <'+'> ))) + if (!(VIMAP_PARSER_TRY_CHECK(one_char <'+'> ))) { VIMAP_PARSER_CHECK(one_char <'-'> ); + } shared_ptr nz; VIMAP_PARSER_GET_PTR(number, nz); @@ -2591,55 +2603,53 @@ public: const string month(utility::stringUtils::toLower(amo->value())); int mon = vmime::datetime::JANUARY; - if (month.length() >= 3) - { - switch (month[0]) - { - case 'j': - { - switch (month[1]) - { - case 'a': mon = vmime::datetime::JANUARY; break; - case 'u': - { - switch (month[2]) - { - case 'n': mon = vmime::datetime::JUNE; break; - default: mon = vmime::datetime::JULY; break; + if (month.length() >= 3) { + + switch (month[0]) { + + case 'j': { + + switch (month[1]) { + + case 'a': mon = vmime::datetime::JANUARY; break; + case 'u': { + + switch (month[2]) { + + case 'n': mon = vmime::datetime::JUNE; break; + default: mon = vmime::datetime::JULY; break; + } + + break; + } + } break; } + case 'f': mon = vmime::datetime::FEBRUARY; break; + case 'm': { + switch (month[2]) { + case 'r': mon = vmime::datetime::MARCH; break; + default: mon = vmime::datetime::MAY; break; + } + + break; } - - break; - } - case 'f': mon = vmime::datetime::FEBRUARY; break; - case 'm': - { - switch (month[2]) + case 'a': { - case 'r': mon = vmime::datetime::MARCH; break; - default: mon = vmime::datetime::MAY; break; - } + switch (month[1]) { + case 'p': mon = vmime::datetime::APRIL; break; + default: mon = vmime::datetime::AUGUST; break; + } - break; - } - case 'a': - { - switch (month[1]) - { - case 'p': mon = vmime::datetime::APRIL; break; - default: mon = vmime::datetime::AUGUST; break; + break; } - - break; - } - case 's': mon = vmime::datetime::SEPTEMBER; break; - case 'o': mon = vmime::datetime::OCTOBER; break; - case 'n': mon = vmime::datetime::NOVEMBER; break; - case 'd': mon = vmime::datetime::DECEMBER; break; + case 's': mon = vmime::datetime::SEPTEMBER; break; + case 'o': mon = vmime::datetime::OCTOBER; break; + case 'n': mon = vmime::datetime::NOVEMBER; break; + case 'd': mon = vmime::datetime::DECEMBER; break; } } @@ -2669,23 +2679,22 @@ public: DECLARE_COMPONENT(header_list) - ~header_list() - { + ~header_list() { + for (std::vector ::iterator it = m_fld_names.begin() ; - it != m_fld_names.end() ; ++it) - { - delete (*it); + it != m_fld_names.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_GET_PUSHBACK(header_fld_name, m_fld_names); VIMAP_PARSER_TRY_CHECK(SPACE); } @@ -2718,40 +2727,41 @@ public: DECLARE_COMPONENT(body_extension) body_extension() - : m_nstring(NULL), m_number(NULL) - { + : m_nstring(NULL), + m_number(NULL) { + } - ~body_extension() - { - delete (m_nstring); - delete (m_number); + ~body_extension() { + + delete m_nstring; + delete m_number; for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); + it != m_body_extensions.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) { + VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); VIMAP_PARSER_TRY_CHECK(SPACE); } - } - else - { - if (!VIMAP_PARSER_TRY_GET(IMAPParser::nstring, m_nstring)) + + } else { + + if (!VIMAP_PARSER_TRY_GET(IMAPParser::nstring, m_nstring)) { VIMAP_PARSER_GET(IMAPParser::number, m_number); + } } *currentPos = pos; @@ -2783,43 +2793,43 @@ public: DECLARE_COMPONENT(section_text) section_text() - : m_header_list(NULL) - { + : m_header_list(NULL) { + } - ~section_text() - { - delete (m_header_list); + ~section_text() { + + delete m_header_list; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // "HEADER.FIELDS" [".NOT"] SPACE header_list const bool b1 = VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "header.fields.not"); const bool b2 = (b1 ? false : VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "header.fields")); - if (b1 || b2) - { + if (b1 || b2) { + m_type = b1 ? HEADER_FIELDS_NOT : HEADER_FIELDS; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::header_list, m_header_list); - } + // "HEADER" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "header")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "header")) { + m_type = HEADER; - } + // "MIME" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "mime")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "mime")) { + m_type = MIME; - } + // "TEXT" - else - { + } else { + m_type = TEXT; VIMAP_PARSER_CHECK_WITHARG(special_atom, "text"); @@ -2831,8 +2841,7 @@ public: } - enum Type - { + enum Type { HEADER, HEADER_FIELDS, HEADER_FIELDS_NOT, @@ -2860,38 +2869,36 @@ public: DECLARE_COMPONENT(section) section() - : m_section_text1(NULL), m_section_text2(NULL) - { + : m_section_text1(NULL), + m_section_text2(NULL) { + } - ~section() - { - delete (m_section_text1); - delete (m_section_text2); + ~section() { + + delete m_section_text1; + delete m_section_text2; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'['> ); - if (!VIMAP_PARSER_TRY_CHECK(one_char <']'> )) - { - if (!VIMAP_PARSER_TRY_GET(section_text, m_section_text1)) - { + if (!VIMAP_PARSER_TRY_CHECK(one_char <']'> )) { + + if (!VIMAP_PARSER_TRY_GET(section_text, m_section_text1)) { + shared_ptr num; VIMAP_PARSER_GET_PTR(nz_number, num); m_nz_numbers.push_back(static_cast (num->value())); - while (VIMAP_PARSER_TRY_CHECK(one_char <'.'> )) - { - if (VIMAP_PARSER_TRY_GET_PTR(nz_number, num)) - { + while (VIMAP_PARSER_TRY_CHECK(one_char <'.'> )) { + + if (VIMAP_PARSER_TRY_GET_PTR(nz_number, num)) { m_nz_numbers.push_back(static_cast (num->value())); - } - else - { + } else { VIMAP_PARSER_GET(section_text, m_section_text2); break; } @@ -2946,21 +2953,23 @@ public: DECLARE_COMPONENT(address) address() - : m_addr_name(NULL), m_addr_adl(NULL), - m_addr_mailbox(NULL), m_addr_host(NULL) - { + : m_addr_name(NULL), + m_addr_adl(NULL), + m_addr_mailbox(NULL), + m_addr_host(NULL) { + } - ~address() - { - delete (m_addr_name); - delete (m_addr_adl); - delete (m_addr_mailbox); - delete (m_addr_host); + ~address() { + + delete m_addr_name; + delete m_addr_adl; + delete m_addr_mailbox; + delete m_addr_host; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); @@ -3000,25 +3009,24 @@ public: DECLARE_COMPONENT(address_list) - ~address_list() - { + ~address_list() { + for (std::vector ::iterator it = m_addresses.begin() ; - it != m_addresses.end() ; ++it) - { + it != m_addresses.end() ; ++it) { + delete (*it); } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!VIMAP_PARSER_TRY_CHECK(NIL)) - { + if (!VIMAP_PARSER_TRY_CHECK(NIL)) { + VIMAP_PARSER_CHECK(one_char <'('> ); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_GET_PUSHBACK(address, m_addresses); VIMAP_PARSER_TRY_CHECK(SPACE); } @@ -3119,29 +3127,35 @@ public: DECLARE_COMPONENT(envelope) envelope() - : m_env_date(NULL), m_env_subject(NULL), - m_env_from(NULL), m_env_sender(NULL), m_env_reply_to(NULL), - m_env_to(NULL), m_env_cc(NULL), m_env_bcc(NULL), - m_env_in_reply_to(NULL), m_env_message_id(NULL) - { + : m_env_date(NULL), + m_env_subject(NULL), + m_env_from(NULL), + m_env_sender(NULL), + m_env_reply_to(NULL), + m_env_to(NULL), + m_env_cc(NULL), + m_env_bcc(NULL), + m_env_in_reply_to(NULL), + m_env_message_id(NULL) { + } - ~envelope() - { - delete (m_env_date); - delete (m_env_subject); - delete (m_env_from); - delete (m_env_sender); - delete (m_env_reply_to); - delete (m_env_to); - delete (m_env_cc); - delete (m_env_bcc); - delete (m_env_in_reply_to); - delete (m_env_message_id); + ~envelope() { + + delete m_env_date; + delete m_env_subject; + delete m_env_from; + delete m_env_sender; + delete m_env_reply_to; + delete m_env_to; + delete m_env_cc; + delete m_env_bcc; + delete m_env_in_reply_to; + delete m_env_message_id; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); @@ -3250,25 +3264,26 @@ public: // "QUOTED-PRINTABLE") <">) / string // - class body_fld_enc : public nstring - { + class body_fld_enc : public nstring { + public: - const string getComponentName() const - { + const string getComponentName() const { + return "body_fld_enc"; } - body_fld_enc() - { + body_fld_enc() { + } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!xstring::parseImpl(parser, line, &pos)) + if (!xstring::parseImpl(parser, line, &pos)) { return false; + } // " When an IMAP4 client sends a FETCH (bodystructure) request // to a server that is running the Exchange Server 2007 IMAP4 @@ -3276,8 +3291,7 @@ public: // (see http://support.microsoft.com/kb/975918/en-us) // // Fail in strict mode - if (isNIL() && parser.isStrict()) - { + if (isNIL() && parser.isStrict()) { VIMAP_PARSER_FAIL(); } @@ -3295,51 +3309,52 @@ public: DECLARE_COMPONENT(body_fld_param_item) body_fld_param_item() - : m_string1(NULL), m_string2(NULL) - { + : m_string1(NULL), + m_string2(NULL) { + } - ~body_fld_param_item() - { - delete (m_string1); - delete (m_string2); + ~body_fld_param_item() { + + delete m_string1; + delete m_string2; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!parser.isStrict()) - { + if (!parser.isStrict()) { + // Some servers send an instead of a here: // eg. ... (CHARSET "X-UNKNOWN") ... - if (!VIMAP_PARSER_TRY_GET(xstring, m_string1)) - { + if (!VIMAP_PARSER_TRY_GET(xstring, m_string1)) { + shared_ptr at; VIMAP_PARSER_GET_PTR(atom, at); m_string1 = new xstring(); m_string1->setValue(at->value()); } - } - else - { + + } else { + VIMAP_PARSER_GET(xstring, m_string1); } VIMAP_PARSER_CHECK(SPACE); - if (!parser.isStrict()) - { + if (!parser.isStrict()) { + // In non-strict mode, allow NIL in value shared_ptr nstr; VIMAP_PARSER_GET_PTR(nstring, nstr); m_string2 = new xstring(); m_string2->setValue(nstr->value()); - } - else - { + + } else { + VIMAP_PARSER_GET(xstring, m_string2); } @@ -3368,31 +3383,30 @@ public: DECLARE_COMPONENT(body_fld_param) - ~body_fld_param() - { + ~body_fld_param() { + for (std::vector ::iterator it = m_items.begin() ; - it != m_items.end() ; ++it) - { - delete (*it); + it != m_items.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) { + VIMAP_PARSER_GET_PUSHBACK(body_fld_param_item, m_items); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET_PUSHBACK(body_fld_param_item, m_items); } - } - else - { + + } else { + VIMAP_PARSER_CHECK(NIL); } @@ -3418,29 +3432,30 @@ public: DECLARE_COMPONENT(body_fld_dsp) body_fld_dsp() - : m_string(NULL), m_body_fld_param(NULL) - { + : m_string(NULL), + m_body_fld_param(NULL) { + } - ~body_fld_dsp() - { - delete (m_string); - delete (m_body_fld_param); + ~body_fld_dsp() { + + delete m_string; + delete m_body_fld_param; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) { + VIMAP_PARSER_GET(xstring, m_string); VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(class body_fld_param, m_body_fld_param); VIMAP_PARSER_CHECK(one_char <')'> ); - } - else - { + + } else { + VIMAP_PARSER_CHECK(NIL); } @@ -3467,31 +3482,30 @@ public: DECLARE_COMPONENT(body_fld_lang) - ~body_fld_lang() - { + ~body_fld_lang() { + for (std::vector ::iterator it = m_strings.begin() ; - it != m_strings.end() ; ++it) - { - delete (*it); + it != m_strings.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'('> )) { + VIMAP_PARSER_GET_PUSHBACK(xstring, m_strings); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET_PUSHBACK(xstring, m_strings); } - } - else - { + + } else { + VIMAP_PARSER_GET_PUSHBACK(nstring, m_strings); } @@ -3519,22 +3533,25 @@ public: DECLARE_COMPONENT(body_fields) body_fields() - : m_body_fld_param(NULL), m_body_fld_id(NULL), - m_body_fld_desc(NULL), m_body_fld_enc(NULL), m_body_fld_octets(NULL) - { + : m_body_fld_param(NULL), + m_body_fld_id(NULL), + m_body_fld_desc(NULL), + m_body_fld_enc(NULL), + m_body_fld_octets(NULL) { + } - ~body_fields() - { - delete (m_body_fld_param); - delete (m_body_fld_id); - delete (m_body_fld_desc); - delete (m_body_fld_enc); - delete (m_body_fld_octets); + ~body_fields() { + + delete m_body_fld_param; + delete m_body_fld_id; + delete m_body_fld_desc; + delete m_body_fld_enc; + delete m_body_fld_octets; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::body_fld_param, m_body_fld_param); @@ -3586,17 +3603,17 @@ public: DECLARE_COMPONENT(media_text) media_text() - : m_media_subtype(NULL) - { + : m_media_subtype(NULL) { + } - ~media_text() - { - delete (m_media_subtype); + ~media_text() { + + delete m_media_subtype; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'"'> ); @@ -3629,17 +3646,17 @@ public: DECLARE_COMPONENT(media_message) media_message() - : m_media_subtype(NULL) - { + : m_media_subtype(NULL) { + } - ~media_message() - { + ~media_message() { + delete m_media_subtype; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'"'> ); @@ -3677,18 +3694,19 @@ public: DECLARE_COMPONENT(media_basic) media_basic() - : m_media_type(NULL), m_media_subtype(NULL) - { + : m_media_type(NULL), + m_media_subtype(NULL) { + } - ~media_basic() - { - delete (m_media_type); - delete (m_media_subtype); + ~media_basic() { + + delete m_media_type; + delete m_media_subtype; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(xstring, m_media_type); @@ -3725,20 +3743,22 @@ public: DECLARE_COMPONENT(body_ext_1part) body_ext_1part() - : m_body_fld_md5(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) - { + : m_body_fld_md5(NULL), + m_body_fld_dsp(NULL), + m_body_fld_lang(NULL) { + } - ~body_ext_1part() - { - delete (m_body_fld_md5); - delete (m_body_fld_dsp); - delete (m_body_fld_lang); + ~body_ext_1part() { + + delete m_body_fld_md5; + delete m_body_fld_dsp; + delete m_body_fld_lang; for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); + it != m_body_extensions.end() ; ++it) { + + delete *it; } } @@ -3749,22 +3769,23 @@ public: VIMAP_PARSER_GET(IMAPParser::body_fld_md5, m_body_fld_md5); // [SPACE body_fld_dsp - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET(IMAPParser::body_fld_dsp, m_body_fld_dsp); // [SPACE body_fld_lang - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET(IMAPParser::body_fld_lang, m_body_fld_lang); // [SPACE 1#body_extension] - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); + } } } } @@ -3802,45 +3823,48 @@ public: DECLARE_COMPONENT(body_ext_mpart) body_ext_mpart() - : m_body_fld_param(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) - { + : m_body_fld_param(NULL), + m_body_fld_dsp(NULL), + m_body_fld_lang(NULL) { + } - ~body_ext_mpart() - { - delete (m_body_fld_param); - delete (m_body_fld_dsp); - delete (m_body_fld_lang); + ~body_ext_mpart() { + + delete m_body_fld_param; + delete m_body_fld_dsp; + delete m_body_fld_lang; for (std::vector ::iterator it = m_body_extensions.begin() ; - it != m_body_extensions.end() ; ++it) - { - delete (*it); + it != m_body_extensions.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::body_fld_param, m_body_fld_param); // [SPACE body_fld_dsp [SPACE body_fld_lang [SPACE 1#body_extension]]] - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET(IMAPParser::body_fld_dsp, m_body_fld_dsp); - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET(IMAPParser::body_fld_lang, m_body_fld_lang); // [SPACE 1#body_extension] - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET_PUSHBACK(body_extension, m_body_extensions); + } } } } @@ -3876,18 +3900,19 @@ public: DECLARE_COMPONENT(body_type_basic) body_type_basic() - : m_media_basic(NULL), m_body_fields(NULL) - { + : m_media_basic(NULL), + m_body_fields(NULL) { + } - ~body_type_basic() - { - delete (m_media_basic); - delete (m_body_fields); + ~body_type_basic() { + + delete m_media_basic; + delete m_body_fields; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::media_basic, m_media_basic); @@ -3922,22 +3947,25 @@ public: DECLARE_COMPONENT(body_type_msg) body_type_msg() - : m_media_message(NULL), m_body_fields(NULL), - m_envelope(NULL), m_body(NULL), m_body_fld_lines(NULL) - { + : m_media_message(NULL), + m_body_fields(NULL), + m_envelope(NULL), + m_body(NULL), + m_body_fld_lines(NULL) { + } - ~body_type_msg() - { - delete (m_media_message); - delete (m_body_fields); - delete (m_envelope); - delete (m_body); - delete (m_body_fld_lines); + ~body_type_msg() { + + delete m_media_message; + delete m_body_fields; + delete m_envelope; + delete m_body; + delete m_body_fld_lines; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::media_message, m_media_message); @@ -3984,19 +4012,20 @@ public: body_type_text() : m_media_text(NULL), - m_body_fields(NULL), m_body_fld_lines(NULL) - { + m_body_fields(NULL), + m_body_fld_lines(NULL) { + } - ~body_type_text() - { - delete (m_media_text); - delete (m_body_fields); - delete (m_body_fld_lines); + ~body_type_text() { + + delete m_media_text; + delete m_body_fields; + delete m_body_fld_lines; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET(IMAPParser::media_text, m_media_text); @@ -4032,32 +4061,35 @@ public: DECLARE_COMPONENT(body_type_1part) body_type_1part() - : m_body_type_basic(NULL), m_body_type_msg(NULL), - m_body_type_text(NULL), m_body_ext_1part(NULL) - { + : m_body_type_basic(NULL), + m_body_type_msg(NULL), + m_body_type_text(NULL), + m_body_ext_1part(NULL) { + } - ~body_type_1part() - { - delete (m_body_type_basic); - delete (m_body_type_msg); - delete (m_body_type_text); + ~body_type_1part() { - delete (m_body_ext_1part); + delete m_body_type_basic; + delete m_body_type_msg; + delete m_body_type_text; + delete m_body_ext_1part; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_text, m_body_type_text)) - if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_msg, m_body_type_msg)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_text, m_body_type_text)) { + if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_msg, m_body_type_msg)) { VIMAP_PARSER_GET(IMAPParser::body_type_basic, m_body_type_basic); + } + } - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { - if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_ext_1part, m_body_ext_1part)) + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_ext_1part, m_body_ext_1part)) { --pos; + } } *currentPos = pos; @@ -4091,30 +4123,30 @@ public: DECLARE_COMPONENT(body_type_mpart) body_type_mpart() - : m_media_subtype(NULL), m_body_ext_mpart(NULL) - { + : m_media_subtype(NULL), + m_body_ext_mpart(NULL) { + } - ~body_type_mpart() - { - delete (m_media_subtype); - delete (m_body_ext_mpart); + ~body_type_mpart() { + + delete m_media_subtype; + delete m_body_ext_mpart; for (std::vector ::iterator it = m_list.begin() ; - it != m_list.end() ; ++it) - { - delete (*it); + it != m_list.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_GET_PUSHBACK(xbody, m_list); - while (true) - { + while (true) { VIMAP_PARSER_TRY_GET_PUSHBACK_OR_ELSE(xbody, m_list, break); } @@ -4122,8 +4154,9 @@ public: VIMAP_PARSER_GET(IMAPParser::media_subtype, m_media_subtype); - if (VIMAP_PARSER_TRY_CHECK(SPACE)) + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET(IMAPParser::body_ext_mpart, m_body_ext_mpart); + } *currentPos = pos; @@ -4153,24 +4186,26 @@ public: DECLARE_COMPONENT(xbody) xbody() - : m_body_type_1part(NULL), m_body_type_mpart(NULL) - { + : m_body_type_1part(NULL), + m_body_type_mpart(NULL) { + } - ~xbody() - { - delete (m_body_type_1part); - delete (m_body_type_mpart); + ~xbody() { + + delete m_body_type_1part; + delete m_body_type_mpart; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); - if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_mpart, m_body_type_mpart)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::body_type_mpart, m_body_type_mpart)) { VIMAP_PARSER_GET(IMAPParser::body_type_1part, m_body_type_1part); + } VIMAP_PARSER_CHECK(one_char <')'> ); @@ -4207,139 +4242,141 @@ public: DECLARE_COMPONENT(msg_att_item) msg_att_item() - : m_date_time(NULL), m_number(NULL), m_envelope(NULL), - m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL), - m_section(NULL), m_mod_sequence_value(NULL) + : m_date_time(NULL), + m_number(NULL), + m_envelope(NULL), + m_uniqueid(NULL), + m_nstring(NULL), + m_body(NULL), + m_flag_list(NULL), + m_section(NULL), + m_mod_sequence_value(NULL) { - { } - ~msg_att_item() - { - delete (m_date_time); - delete (m_number); - delete (m_envelope); - delete (m_uniqueid); - delete (m_nstring); - delete (m_body); - delete (m_flag_list); - delete (m_section); + ~msg_att_item() { + + delete m_date_time; + delete m_number; + delete m_envelope; + delete m_uniqueid; + delete m_nstring; + delete m_body; + delete m_flag_list; + delete m_section; delete m_mod_sequence_value; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // "ENVELOPE" SPACE envelope - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "envelope")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "envelope")) { + m_type = ENVELOPE; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::envelope, m_envelope); - } + // "FLAGS" SPACE "(" #(flag / "\Recent") ")" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "flags")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "flags")) { + m_type = FLAGS; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::flag_list, m_flag_list); - } + // "INTERNALDATE" SPACE date_time - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "internaldate")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "internaldate")) { + m_type = INTERNALDATE; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::date_time, m_date_time); - } + // "RFC822" ".HEADER" SPACE nstring - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.header")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.header")) { + m_type = RFC822_HEADER; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nstring, m_nstring); - } + // "RFC822" ".TEXT" SPACE nstring - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.text")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.text")) { + m_type = RFC822_TEXT; VIMAP_PARSER_CHECK(SPACE); - m_nstring = parser.getWithArgs - (line, &pos, this, RFC822_TEXT); + m_nstring = parser.getWithArgs (line, &pos, this, RFC822_TEXT); VIMAP_PARSER_FAIL_UNLESS(m_nstring); - } + // "RFC822.SIZE" SPACE number - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.size")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822.size")) { + m_type = RFC822_SIZE; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::number, m_number); - } + // "RFC822" SPACE nstring - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "rfc822")) { + m_type = RFC822; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nstring, m_nstring); - } + // "BODY" "STRUCTURE" SPACE body - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "bodystructure")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "bodystructure")) { + m_type = BODY_STRUCTURE; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::body, m_body); - } + // "BODY" section ["<" number ">"] SPACE nstring // "BODY" SPACE body - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "body")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "body")) { + VIMAP_PARSER_TRY_GET(IMAPParser::section, m_section); // "BODY" section ["<" number ">"] SPACE nstring - if (m_section != NULL) - { + if (m_section != NULL) { + m_type = BODY_SECTION; - if (VIMAP_PARSER_TRY_CHECK(one_char <'<'> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'<'> )) { VIMAP_PARSER_GET(IMAPParser::number, m_number); VIMAP_PARSER_CHECK(one_char <'>'> ); } VIMAP_PARSER_CHECK(SPACE); - m_nstring = parser.getWithArgs - (line, &pos, this, BODY_SECTION); + m_nstring = parser.getWithArgs (line, &pos, this, BODY_SECTION); VIMAP_PARSER_FAIL_UNLESS(m_nstring); - } + // "BODY" SPACE body - else - { + } else { + m_type = BODY; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::body, m_body); } - } + // "MODSEQ" SP "(" mod_sequence_value ")" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "modseq")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "modseq")) { + m_type = MODSEQ; VIMAP_PARSER_CHECK(SPACE); @@ -4348,10 +4385,10 @@ public: VIMAP_PARSER_GET(IMAPParser::mod_sequence_value, m_mod_sequence_value); VIMAP_PARSER_CHECK(one_char <')'> ); - } + // "UID" SPACE uniqueid - else - { + } else { + m_type = UID; VIMAP_PARSER_CHECK_WITHARG(special_atom, "uid"); @@ -4366,8 +4403,7 @@ public: } - enum Type - { + enum Type { ENVELOPE, FLAGS, INTERNALDATE, @@ -4418,25 +4454,24 @@ public: DECLARE_COMPONENT(msg_att) - ~msg_att() - { + ~msg_att() { + for (std::vector ::iterator it = m_items.begin() ; - it != m_items.end() ; ++it) - { - delete (*it); + it != m_items.end() ; ++it) { + + delete *it; } } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'('> ); m_items.push_back(parser.get (line, &pos)); - while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) - { + while (!VIMAP_PARSER_TRY_CHECK(one_char <')'> )) { VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET_PUSHBACK(msg_att_item, m_items); } @@ -4464,17 +4499,18 @@ public: DECLARE_COMPONENT(message_data) message_data() - : m_number(0), m_msg_att(NULL) - { + : m_number(0), + m_msg_att(NULL) { + } - ~message_data() - { - delete (m_msg_att); + ~message_data() { + + delete m_msg_att; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; scoped_ptr num; @@ -4483,12 +4519,12 @@ public: VIMAP_PARSER_CHECK(SPACE); - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "expunge")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "expunge")) { + m_type = EXPUNGE; - } - else - { + + } else { + m_type = FETCH; VIMAP_PARSER_CHECK_WITHARG(special_atom, "fetch"); @@ -4502,8 +4538,7 @@ public: } - enum Type - { + enum Type { EXPUNGE, FETCH }; @@ -4547,122 +4582,125 @@ public: DECLARE_COMPONENT(resp_text_code) resp_text_code() - : m_nz_number(NULL), m_atom(NULL), m_flag_list(NULL), - m_text(NULL), m_capability_data(NULL) - { + : m_nz_number(NULL), + m_atom(NULL), + m_flag_list(NULL), + m_text(NULL), + m_capability_data(NULL) { + } - ~resp_text_code() - { - delete (m_nz_number); - delete (m_atom); - delete (m_flag_list); - delete (m_text); + ~resp_text_code() { + + delete m_nz_number; + delete m_atom; + delete m_flag_list; + delete m_text; delete m_capability_data; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; // "ALERT" - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "alert")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "alert")) { + m_type = ALERT; - } + // "PARSE" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "parse")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "parse")) { + m_type = PARSE; - } + // capability_data - else if (VIMAP_PARSER_TRY_GET(IMAPParser::capability_data, m_capability_data)) - { + } else if (VIMAP_PARSER_TRY_GET(IMAPParser::capability_data, m_capability_data)) { + m_type = CAPABILITY; - } + // "PERMANENTFLAGS" SPACE flag_list - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "permanentflags")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "permanentflags")) { + m_type = PERMANENTFLAGS; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::flag_list, m_flag_list); - } + // "READ-ONLY" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "read-only")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "read-only")) { + m_type = READ_ONLY; - } + // "READ-WRITE" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "read-write")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "read-write")) { + m_type = READ_WRITE; - } + // "TRYCREATE" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "trycreate")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "trycreate")) { + m_type = TRYCREATE; - } + // "UIDVALIDITY" SPACE nz_number - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidvalidity")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidvalidity")) { + m_type = UIDVALIDITY; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nz_number, m_nz_number); - } + // "UIDNEXT" SPACE nz_number - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnext")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnext")) { + m_type = UIDNEXT; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nz_number, m_nz_number); - } + // "UNSEEN" SPACE nz_number - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "unseen")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "unseen")) { + m_type = UNSEEN; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nz_number, m_nz_number); - } + // "HIGHESTMODSEQ" SP mod-sequence-value - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "highestmodseq")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "highestmodseq")) { + m_type = HIGHESTMODSEQ; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::mod_sequence_value, m_mod_sequence_value); - } + // "NOMODSEQ" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "nomodseq")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "nomodseq")) { + m_type = NOMODSEQ; - } + // "MODIFIED" SP sequence-set - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "modified")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "modified")) { + m_type = MODIFIED; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::sequence_set, m_sequence_set); - } + // "APPENDUID" SP nz-number SP append-uid - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "appenduid")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "appenduid")) { + m_type = APPENDUID; VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::nz_number, m_nz_number); VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::uid_set, m_uid_set); - } + // "COPYUID" SP nz-number SP uid-set SP uid-set - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "copyuid")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "copyuid")) { + m_type = COPYUID; VIMAP_PARSER_CHECK(SPACE); @@ -4671,21 +4709,22 @@ public: VIMAP_PARSER_GET(IMAPParser::uid_set, m_uid_set); VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::uid_set, m_uid_set2); - } + // "UIDNOTSTICKY" - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnotsticky")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "uidnotsticky")) { + m_type = UIDNOTSTICKY; - } + // atom [SPACE 1*] - else - { + } else { + m_type = OTHER; VIMAP_PARSER_GET(IMAPParser::atom, m_atom); - if (VIMAP_PARSER_TRY_CHECK(SPACE)) + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET(text_except <']'> , m_text); + } } *currentPos = pos; @@ -4694,8 +4733,7 @@ public: } - enum Type - { + enum Type { // Extensions HIGHESTMODSEQ, NOMODSEQ, @@ -4755,21 +4793,21 @@ public: DECLARE_COMPONENT(resp_text) resp_text() - : m_resp_text_code(NULL) - { + : m_resp_text_code(NULL) { + } - ~resp_text() - { - delete (m_resp_text_code); + ~resp_text() { + + delete m_resp_text_code; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK(one_char <'['> )) - { + if (VIMAP_PARSER_TRY_CHECK(one_char <'['> )) { + VIMAP_PARSER_GET(IMAPParser::resp_text_code, m_resp_text_code); VIMAP_PARSER_CHECK(one_char <']'> ); @@ -4779,21 +4817,18 @@ public: scoped_ptr text1; VIMAP_PARSER_TRY_GET_PTR(text_mime2, text1); - if (text1.get()) - { + if (text1.get()) { + m_text = text1->value(); - } - else - { + + } else { + scoped_ptr text2; VIMAP_PARSER_TRY_GET_PTR(IMAPParser::text, text2); - if (text2.get()) - { + if (text2.get()) { m_text = text2->value(); - } - else - { + } else { // Empty response text } } @@ -4822,35 +4857,32 @@ public: DECLARE_COMPONENT(continue_req) continue_req() - : m_resp_text(NULL) - { + : m_resp_text(NULL) { + } - ~continue_req() - { - delete (m_resp_text); + ~continue_req() { + + delete m_resp_text; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'+'> ); - if (!parser.isStrict()) - { + if (!parser.isStrict()) { + // Some servers do not send SPACE when response text is empty - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET(IMAPParser::resp_text, m_resp_text); - } - else - { + } else { m_resp_text = new IMAPParser::resp_text(); // empty } - } - else - { + + } else { + VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::resp_text, m_resp_text); @@ -4881,29 +4913,25 @@ public: DECLARE_COMPONENT(resp_cond_state) resp_cond_state() - : m_resp_text(NULL), m_status(BAD) - { + : m_resp_text(NULL), + m_status(BAD) { + } - ~resp_cond_state() - { - delete (m_resp_text); + ~resp_cond_state() { + + delete m_resp_text; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "ok")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "ok")) { m_status = OK; - } - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "no")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "no")) { m_status = NO; - } - else - { + } else { VIMAP_PARSER_CHECK_WITHARG(special_atom, "bad"); m_status = BAD; } @@ -4918,8 +4946,7 @@ public: } - enum Status - { + enum Status { OK, NO, BAD @@ -4944,17 +4971,17 @@ public: DECLARE_COMPONENT(resp_cond_bye) resp_cond_bye() - : m_resp_text(NULL) - { + : m_resp_text(NULL) { + } - ~resp_cond_bye() - { - delete (m_resp_text); + ~resp_cond_bye() { + + delete m_resp_text; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK_WITHARG(special_atom, "bye"); @@ -4986,27 +5013,23 @@ public: DECLARE_COMPONENT(resp_cond_auth) resp_cond_auth() - : m_resp_text(NULL) - { + : m_resp_text(NULL) { + } - ~resp_cond_auth() - { - delete (m_resp_text); + ~resp_cond_auth() { + + delete m_resp_text; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "ok")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "ok")) { m_cond = OK; - } - else - { + } else { VIMAP_PARSER_CHECK_WITHARG(special_atom, "preauth"); - m_cond = PREAUTH; } @@ -5020,8 +5043,7 @@ public: } - enum Condition - { + enum Condition { OK, PREAUTH }; @@ -5053,102 +5075,103 @@ public: DECLARE_COMPONENT(mailbox_data) mailbox_data() - : m_number(NULL), m_mailbox_flag_list(NULL), m_mailbox_list(NULL), - m_mailbox(NULL), m_text(NULL), m_status_att_list(NULL) - { + : m_number(NULL), + m_mailbox_flag_list(NULL), + m_mailbox_list(NULL), + m_mailbox(NULL), + m_text(NULL), + m_status_att_list(NULL) { + } - ~mailbox_data() - { - delete (m_number); - delete (m_mailbox_flag_list); - delete (m_mailbox_list); - delete (m_mailbox); - delete (m_text); + ~mailbox_data() { + + delete m_number; + delete m_mailbox_flag_list; + delete m_mailbox_list; + delete m_mailbox; + delete m_text; for (std::vector ::iterator it = m_search_nz_number_list.begin() ; - it != m_search_nz_number_list.end() ; ++it) - { - delete (*it); + it != m_search_nz_number_list.end() ; ++it) { + + delete *it; } delete m_status_att_list; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (VIMAP_PARSER_TRY_GET(IMAPParser::number, m_number)) - { + if (VIMAP_PARSER_TRY_GET(IMAPParser::number, m_number)) { + VIMAP_PARSER_CHECK(SPACE); - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "exists")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "exists")) { m_type = EXISTS; - } - else - { + } else { VIMAP_PARSER_CHECK_WITHARG(special_atom, "recent"); - m_type = RECENT; } - } - else - { + + } else { + // "FLAGS" SPACE mailbox_flag_list - if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "flags")) - { + if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "flags")) { + VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::mailbox_flag_list, m_mailbox_flag_list); m_type = FLAGS; - } + // "LIST" SPACE mailbox_list - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "list")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "list")) { + VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::mailbox_list, m_mailbox_list); m_type = LIST; - } + // "LSUB" SPACE mailbox_list - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "lsub")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "lsub")) { + VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::mailbox_list, m_mailbox_list); m_type = LSUB; - } + // "MAILBOX" SPACE text - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "mailbox")) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "mailbox")) { + VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::text, m_text); m_type = MAILBOX; - } + // "SEARCH" [SPACE 1#nz_number] - else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "search")) - { - if (VIMAP_PARSER_TRY_CHECK(SPACE)) - { + } else if (VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "search")) { + + if (VIMAP_PARSER_TRY_CHECK(SPACE)) { + VIMAP_PARSER_GET_PUSHBACK(nz_number, m_search_nz_number_list); - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { VIMAP_PARSER_GET_PUSHBACK(nz_number, m_search_nz_number_list); + } } m_type = SEARCH; - } + // "STATUS" SPACE mailbox SPACE // "(" [status_att_list] ")" - else - { + } else { + VIMAP_PARSER_CHECK_WITHARG(special_atom, "status"); VIMAP_PARSER_CHECK(SPACE); @@ -5170,8 +5193,8 @@ public: } - enum Type - { + enum Type { + FLAGS, LIST, LSUB, @@ -5216,38 +5239,46 @@ public: DECLARE_COMPONENT(response_data) response_data() - : m_resp_cond_state(NULL), m_resp_cond_bye(NULL), - m_mailbox_data(NULL), m_message_data(NULL), m_capability_data(NULL) - { + : m_resp_cond_state(NULL), + m_resp_cond_bye(NULL), + m_mailbox_data(NULL), + m_message_data(NULL), + m_capability_data(NULL) { + } - ~response_data() - { - delete (m_resp_cond_state); - delete (m_resp_cond_bye); - delete (m_mailbox_data); - delete (m_message_data); - delete (m_capability_data); + ~response_data() { + + delete m_resp_cond_state; + delete m_resp_cond_bye; + delete m_mailbox_data; + delete m_message_data; + delete m_capability_data; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'*'> ); VIMAP_PARSER_CHECK(SPACE); - if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_state, m_resp_cond_state)) - if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_bye, m_resp_cond_bye)) - if (!VIMAP_PARSER_TRY_GET(IMAPParser::mailbox_data, m_mailbox_data)) - if (!VIMAP_PARSER_TRY_GET(IMAPParser::message_data, m_message_data)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_state, m_resp_cond_state)) { + if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_bye, m_resp_cond_bye)) { + if (!VIMAP_PARSER_TRY_GET(IMAPParser::mailbox_data, m_mailbox_data)) { + if (!VIMAP_PARSER_TRY_GET(IMAPParser::message_data, m_message_data)) { VIMAP_PARSER_GET(IMAPParser::capability_data, m_capability_data); + } + } + } + } + + if (!parser.isStrict()) { - if (!parser.isStrict()) - { // Allow SPACEs at end of line - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { ; + } } VIMAP_PARSER_CHECK(CRLF); @@ -5278,22 +5309,24 @@ public: DECLARE_COMPONENT(continue_req_or_response_data) continue_req_or_response_data() - : m_continue_req(NULL), m_response_data(NULL) - { + : m_continue_req(NULL), + m_response_data(NULL) { + } - ~continue_req_or_response_data() - { - delete (m_continue_req); - delete (m_response_data); + ~continue_req_or_response_data() { + + delete m_continue_req; + delete m_response_data; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!VIMAP_PARSER_TRY_GET(IMAPParser::continue_req, m_continue_req)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::continue_req, m_continue_req)) { VIMAP_PARSER_GET(IMAPParser::response_data, m_response_data); + } *currentPos = pos; @@ -5320,17 +5353,17 @@ public: DECLARE_COMPONENT(response_fatal) response_fatal() - : m_resp_cond_bye(NULL) - { + : m_resp_cond_bye(NULL) { + } - ~response_fatal() - { - delete (m_resp_cond_bye); + ~response_fatal() { + + delete m_resp_cond_bye; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'*'> ); @@ -5338,11 +5371,12 @@ public: VIMAP_PARSER_GET(IMAPParser::resp_cond_bye, m_resp_cond_bye); - if (!parser.isStrict()) - { + if (!parser.isStrict()) { + // Allow SPACEs at end of line - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { ; + } } VIMAP_PARSER_CHECK(CRLF); @@ -5369,28 +5403,29 @@ public: DECLARE_COMPONENT(response_tagged) response_tagged() - : m_resp_cond_state(NULL) - { + : m_resp_cond_state(NULL) { + } - ~response_tagged() - { - delete (m_resp_cond_state); + ~response_tagged() { + + delete m_resp_cond_state; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(IMAPParser::xtag); VIMAP_PARSER_CHECK(SPACE); VIMAP_PARSER_GET(IMAPParser::resp_cond_state, m_resp_cond_state); - if (!parser.isStrict()) - { + if (!parser.isStrict()) { + // Allow SPACEs at end of line - while (VIMAP_PARSER_TRY_CHECK(SPACE)) + while (VIMAP_PARSER_TRY_CHECK(SPACE)) { ; + } } VIMAP_PARSER_CHECK(CRLF); @@ -5417,22 +5452,24 @@ public: DECLARE_COMPONENT(response_done) response_done() - : m_response_tagged(NULL), m_response_fatal(NULL) - { + : m_response_tagged(NULL), + m_response_fatal(NULL) { + } - ~response_done() - { - delete (m_response_tagged); - delete (m_response_fatal); + ~response_done() { + + delete m_response_tagged; + delete m_response_fatal; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; - if (!VIMAP_PARSER_TRY_GET(IMAPParser::response_tagged, m_response_tagged)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::response_tagged, m_response_tagged)) { VIMAP_PARSER_GET(IMAPParser::response_fatal, m_response_fatal); + } *currentPos = pos; @@ -5458,37 +5495,36 @@ public: DECLARE_COMPONENT(response) response() - : m_response_done(NULL) - { + : m_response_done(NULL) { + } - ~response() - { + ~response() { + for (std::vector ::iterator it = m_continue_req_or_response_data.begin() ; - it != m_continue_req_or_response_data.end() ; ++it) - { - delete (*it); + it != m_continue_req_or_response_data.end() ; ++it) { + + delete *it; } - delete (m_response_done); + delete m_response_done; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; string curLine = line; bool partial = false; // partial response IMAPParser::continue_req_or_response_data* resp = NULL; - while ((resp = parser.get (curLine, &pos))) - { + while ((resp = parser.get (curLine, &pos))) { + m_continue_req_or_response_data.push_back(resp); // Partial response (continue_req) - if (resp->continue_req()) - { + if (resp->continue_req()) { partial = true; break; } @@ -5498,8 +5534,7 @@ public: pos = 0; } - if (!partial) - { + if (!partial) { m_response_done = parser.get (curLine, &pos); VIMAP_PARSER_FAIL_UNLESS(m_response_done); } @@ -5510,30 +5545,32 @@ public: } - bool isBad() const - { - if (!response_done()) // incomplete (partial) response - return (true); + bool isBad() const { - if (response_done()->response_fatal()) - return (true); - - if (response_done()->response_tagged()->resp_cond_state()-> - status() == IMAPParser::resp_cond_state::BAD) - { - return (true); + if (!response_done()) { // incomplete (partial) response + return true; } - return (false); + if (response_done()->response_fatal()) { + return true; + } + + if (response_done()->response_tagged()->resp_cond_state()-> + status() == IMAPParser::resp_cond_state::BAD) { + + return true; + } + + return false; } - void setErrorLog(const string& errorLog) - { + void setErrorLog(const string& errorLog) { + m_errorLog = errorLog; } - const string& getErrorLog() const - { + const string& getErrorLog() const { + return m_errorLog; } @@ -5558,25 +5595,27 @@ public: DECLARE_COMPONENT(greeting) greeting() - : m_resp_cond_auth(NULL), m_resp_cond_bye(NULL) - { + : m_resp_cond_auth(NULL), + m_resp_cond_bye(NULL) { + } - ~greeting() - { - delete (m_resp_cond_auth); - delete (m_resp_cond_bye); + ~greeting() { + + delete m_resp_cond_auth; + delete m_resp_cond_bye; } - bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) - { + bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos) { + size_t pos = *currentPos; VIMAP_PARSER_CHECK(one_char <'*'> ); VIMAP_PARSER_CHECK(SPACE); - if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_auth, m_resp_cond_auth)) + if (!VIMAP_PARSER_TRY_GET(IMAPParser::resp_cond_auth, m_resp_cond_auth)) { VIMAP_PARSER_GET(IMAPParser::resp_cond_bye, m_resp_cond_bye); + } VIMAP_PARSER_CHECK(CRLF); @@ -5585,13 +5624,13 @@ public: return true; } - void setErrorLog(const string& errorLog) - { + void setErrorLog(const string& errorLog) { + m_errorLog = errorLog; } - const string& getErrorLog() const - { + const string& getErrorLog() const { + return m_errorLog; } @@ -5614,8 +5653,8 @@ public: // The main functions used to parse a response // - response* readResponse(literalHandler* lh = NULL) - { + response* readResponse(literalHandler* lh = NULL) { + size_t pos = 0; string line = readLine(); @@ -5623,8 +5662,9 @@ public: response* resp = get (line, &pos); m_literalHandler = NULL; - if (!resp) + if (!resp) { throw exceptions::invalid_response("", m_errorResponseLine); + } resp->setErrorLog(lastLine()); @@ -5632,15 +5672,16 @@ public: } - greeting* readGreeting() - { + greeting* readGreeting() { + size_t pos = 0; string line = readLine(); greeting* greet = get (line, &pos); - if (!greet) + if (!greet) { throw exceptions::invalid_response("", m_errorResponseLine); + } greet->setErrorLog(lastLine()); @@ -5659,8 +5700,8 @@ public: * @return a raw pointer to the parsed token, or NULL otherwise */ template - TYPE* get(string& line, size_t* currentPos) - { + TYPE* get(string& line, size_t* currentPos) { + component* resp = new TYPE; return internalGet (resp, line, currentPos); } @@ -5680,9 +5721,8 @@ public: * @return a raw pointer to the parsed token, or NULL otherwise */ template - TYPE* getWithArgs(string& line, size_t* currentPos, - ARG1_TYPE arg1, ARG2_TYPE arg2) - { + TYPE* getWithArgs(string& line, size_t* currentPos, ARG1_TYPE arg1, ARG2_TYPE arg2) { + component* resp = new TYPE(arg1, arg2); return internalGet (resp, line, currentPos); } @@ -5690,15 +5730,15 @@ public: private: template - TYPE* internalGet(component* resp, string& line, size_t* currentPos) - { + TYPE* internalGet(component* resp, string& line, size_t* currentPos) { + const size_t oldPos = *currentPos; - if (!resp->parse(*this, line, currentPos)) - { + if (!resp->parse(*this, line, currentPos)) { + *currentPos = oldPos; - delete (resp); + delete resp; return NULL; } @@ -5706,20 +5746,21 @@ private: return static_cast (resp); } - const string lastLine() const - { + const string lastLine() const { + // Remove blanks and new lines at the end of the line. string line(m_lastLine); string::const_iterator it = line.end(); int count = 0; - while (it != line.begin()) - { + while (it != line.begin()) { + const unsigned char c = *(it - 1); - if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) + if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) { break; + } ++count; --it; @@ -5741,19 +5782,16 @@ public: * @return true if the token has been parsed, or false otherwise */ template - bool check(string& line, size_t* currentPos) - { + bool check(string& line, size_t* currentPos) { + const size_t oldPos = *currentPos; TYPE term; - if (!term.parse(*this, line, currentPos)) - { + if (!term.parse(*this, line, currentPos)) { *currentPos = oldPos; return false; - } - else - { + } else { return true; } } @@ -5769,19 +5807,16 @@ public: * @return true if the token has been parsed, or false otherwise */ template - bool checkWithArg(string& line, size_t* currentPos, const ARG_TYPE arg) - { + bool checkWithArg(string& line, size_t* currentPos, const ARG_TYPE arg) { + const size_t oldPos = *currentPos; TYPE term(arg); - if (!term.parse(*this, line, currentPos)) - { + if (!term.parse(*this, line, currentPos)) { *currentPos = oldPos; return false; - } - else - { + } else { return true; } } @@ -5815,12 +5850,11 @@ public: * * @return next line */ - const string readLine() - { + const string readLine() { + size_t pos; - while ((pos = m_buffer.find('\n')) == string::npos) - { + while ((pos = m_buffer.find('\n')) == string::npos) { read(); } @@ -5836,8 +5870,7 @@ public: std::cout << std::endl << "Read line:" << std::endl << line << std::endl; #endif - if (m_tracer) - { + if (m_tracer) { string::size_type len = line.length(); while (len != 0 && (line[len - 1] == '\r' || line[len - 1] == '\n')) --len; m_tracer->traceReceive(line.substr(0, len)); @@ -5849,84 +5882,90 @@ public: /** Fill in the input buffer with data available from the socket stream. * The function blocks until some data is available. */ - void read() - { + void read() { + string receiveBuffer; shared_ptr toh = m_timeoutHandler.lock(); shared_ptr sok = m_socket.lock(); - if (toh) + if (toh) { toh->resetTimeOut(); + } + + while (receiveBuffer.empty()) { - while (receiveBuffer.empty()) - { // Check whether the time-out delay is elapsed - if (toh && toh->isTimeOut()) - { - if (!toh->handleTimeOut()) + if (toh && toh->isTimeOut()) { + if (!toh->handleTimeOut()) { throw exceptions::operation_timed_out(); + } } // We have received data: reset the time-out counter sok->receive(receiveBuffer); - if (receiveBuffer.empty()) // buffer is empty - { - if (sok->getStatus() & socket::STATUS_WANT_WRITE) + if (receiveBuffer.empty()) { // buffer is empty + + if (sok->getStatus() & socket::STATUS_WANT_WRITE) { sok->waitForWrite(); - else + } else { sok->waitForRead(); + } continue; } // We have received data ... - if (toh) + if (toh) { toh->resetTimeOut(); + } } m_buffer += receiveBuffer; } - void readLiteral(literalHandler::target& buffer, size_t count) - { + void readLiteral(literalHandler::target& buffer, size_t count) { + size_t len = 0; string receiveBuffer; shared_ptr toh = m_timeoutHandler.lock(); shared_ptr sok = m_socket.lock(); - if (m_progress) + if (m_progress) { m_progress->start(count); + } - if (toh) + if (toh) { toh->resetTimeOut(); + } + + if (!m_buffer.empty()) { + + if (m_buffer.length() > count) { - if (!m_buffer.empty()) - { - if (m_buffer.length() > count) - { buffer.putData(string(m_buffer.begin(), m_buffer.begin() + count)); m_buffer.erase(m_buffer.begin(), m_buffer.begin() + count); len = count; - } - else - { + + } else { + len += m_buffer.length(); buffer.putData(m_buffer); m_buffer.clear(); } } - while (len < count) - { + while (len < count) { + // Check whether the time-out delay is elapsed - if (toh && toh->isTimeOut()) - { - if (!toh->handleTimeOut()) + if (toh && toh->isTimeOut()) { + + if (!toh->handleTimeOut()) { throw exceptions::operation_timed_out(); + } toh->resetTimeOut(); } @@ -5934,22 +5973,24 @@ public: // Receive data from the socket sok->receive(receiveBuffer); - if (receiveBuffer.empty()) // buffer is empty - { - if (sok->getStatus() & socket::STATUS_WANT_WRITE) + if (receiveBuffer.empty()) { // buffer is empty + + if (sok->getStatus() & socket::STATUS_WANT_WRITE) { sok->waitForWrite(); - else + } else { sok->waitForRead(); + } continue; } // We have received data: reset the time-out counter - if (toh) + if (toh) { toh->resetTimeOut(); + } + + if (len + receiveBuffer.length() > count) { - if (len + receiveBuffer.length() > count) - { const size_t remaining = count - len; // Get the needed amount of data @@ -5960,23 +6001,26 @@ public: m_buffer += receiveBuffer; len = count; - } - else - { + + } else { + buffer.putData(receiveBuffer); len += receiveBuffer.length(); } // Notify progress - if (m_progress) + if (m_progress) { m_progress->progress(len, count); + } } - if (m_tracer) + if (m_tracer) { m_tracer->traceReceiveBytes(count); + } - if (m_progress) + if (m_progress) { m_progress->stop(count); + } } }; diff --git a/src/vmime/net/imap/IMAPSStore.cpp b/src/vmime/net/imap/IMAPSStore.cpp index f70c0915..dd9c318a 100644 --- a/src/vmime/net/imap/IMAPSStore.cpp +++ b/src/vmime/net/imap/IMAPSStore.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,19 +35,22 @@ namespace net { namespace imap { -IMAPSStore::IMAPSStore(const shared_ptr & sess, const shared_ptr & auth) - : IMAPStore(sess, auth, true) -{ +IMAPSStore::IMAPSStore( + const shared_ptr & sess, + const shared_ptr & auth +) + : IMAPStore(sess, auth, true) { + } -IMAPSStore::~IMAPSStore() -{ +IMAPSStore::~IMAPSStore() { + } -const string IMAPSStore::getProtocolName() const -{ +const string IMAPSStore::getProtocolName() const { + return "imaps"; } @@ -58,14 +61,14 @@ const string IMAPSStore::getProtocolName() const IMAPServiceInfos IMAPSStore::sm_infos(true); -const serviceInfos& IMAPSStore::getInfosInstance() -{ +const serviceInfos& IMAPSStore::getInfosInstance() { + return sm_infos; } -const serviceInfos& IMAPSStore::getInfos() const -{ +const serviceInfos& IMAPSStore::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/imap/IMAPSStore.hpp b/src/vmime/net/imap/IMAPSStore.hpp index 8d6896d7..e18a067f 100644 --- a/src/vmime/net/imap/IMAPSStore.hpp +++ b/src/vmime/net/imap/IMAPSStore.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,9 +41,8 @@ namespace imap { /** IMAPS store service. */ +class VMIME_EXPORT IMAPSStore : public IMAPStore { -class VMIME_EXPORT IMAPSStore : public IMAPStore -{ public: IMAPSStore(const shared_ptr & sess, const shared_ptr & auth); diff --git a/src/vmime/net/imap/IMAPServiceInfos.cpp b/src/vmime/net/imap/IMAPServiceInfos.cpp index 46dbc2e1..baed6ba2 100644 --- a/src/vmime/net/imap/IMAPServiceInfos.cpp +++ b/src/vmime/net/imap/IMAPServiceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,24 +36,24 @@ namespace imap { IMAPServiceInfos::IMAPServiceInfos(const bool imaps) - : m_imaps(imaps) -{ + : m_imaps(imaps) { + } -const string IMAPServiceInfos::getPropertyPrefix() const -{ - if (m_imaps) +const string IMAPServiceInfos::getPropertyPrefix() const { + + if (m_imaps) { return "store.imaps."; - else + } else { return "store.imap."; + } } -const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const -{ - static props imapProps = - { +const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const { + + static props imapProps = { // IMAP-specific options #if VMIME_HAVE_SASL_SUPPORT property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"), @@ -73,8 +73,7 @@ const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const property(serviceInfos::property::SERVER_PORT, "143"), }; - static props imapsProps = - { + static props imapsProps = { // IMAP-specific options #if VMIME_HAVE_SASL_SUPPORT property("options.sasl", serviceInfos::property::TYPE_BOOLEAN, "true"), @@ -98,8 +97,8 @@ const IMAPServiceInfos::props& IMAPServiceInfos::getProperties() const } -const std::vector IMAPServiceInfos::getAvailableProperties() const -{ +const std::vector IMAPServiceInfos::getAvailableProperties() const { + std::vector list; const props& p = getProperties(); @@ -114,8 +113,7 @@ const std::vector IMAPServiceInfos::getAvailablePropert list.push_back(p.PROPERTY_AUTH_PASSWORD); #if VMIME_HAVE_TLS_SUPPORT - if (!m_imaps) - { + if (!m_imaps) { list.push_back(p.PROPERTY_CONNECTION_TLS); list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED); } diff --git a/src/vmime/net/imap/IMAPServiceInfos.hpp b/src/vmime/net/imap/IMAPServiceInfos.hpp index 376f4476..73fca7a0 100644 --- a/src/vmime/net/imap/IMAPServiceInfos.hpp +++ b/src/vmime/net/imap/IMAPServiceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,13 @@ namespace imap { /** Information about IMAP service. */ +class VMIME_EXPORT IMAPServiceInfos : public serviceInfos { -class VMIME_EXPORT IMAPServiceInfos : public serviceInfos -{ public: IMAPServiceInfos(const bool imaps); - struct props - { + struct props { // IMAP-specific options #if VMIME_HAVE_SASL_SUPPORT serviceInfos::property PROPERTY_OPTIONS_SASL; diff --git a/src/vmime/net/imap/IMAPStore.cpp b/src/vmime/net/imap/IMAPStore.cpp index 7abfe8ae..c10e158d 100644 --- a/src/vmime/net/imap/IMAPStore.cpp +++ b/src/vmime/net/imap/IMAPStore.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,130 +44,148 @@ namespace net { namespace imap { -IMAPStore::IMAPStore(const shared_ptr & sess, const shared_ptr & auth, const bool secured) - : store(sess, getInfosInstance(), auth), m_connection(null), m_isIMAPS(secured) -{ +IMAPStore::IMAPStore( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured +) + : store(sess, getInfosInstance(), auth), + m_connection(null), + m_isIMAPS(secured) { + } -IMAPStore::~IMAPStore() -{ - try - { - if (isConnected()) +IMAPStore::~IMAPStore() { + + try { + + if (isConnected()) { disconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -const string IMAPStore::getProtocolName() const -{ +const string IMAPStore::getProtocolName() const { + return "imap"; } -shared_ptr IMAPStore::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr IMAPStore::getRootFolder() { - return shared_ptr - (new IMAPFolder(folder::path(), - dynamicCast (shared_from_this()), - shared_ptr ())); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return make_shared ( + folder::path(), + dynamicCast (shared_from_this()), + shared_ptr () + ); } -shared_ptr IMAPStore::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr IMAPStore::getDefaultFolder() { - return shared_ptr - (new IMAPFolder(folder::path::component("INBOX"), - dynamicCast (shared_from_this()), - shared_ptr ())); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return make_shared ( + folder::path::component("INBOX"), + dynamicCast (shared_from_this()), + shared_ptr () + ); } -shared_ptr IMAPStore::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr IMAPStore::getFolder(const folder::path& path) { - return shared_ptr - (new IMAPFolder(path, - dynamicCast (shared_from_this()), - shared_ptr ())); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return make_shared ( + path, + dynamicCast (shared_from_this()), + shared_ptr () + ); } -bool IMAPStore::isValidFolderName(const folder::path::component& /* name */) const -{ +bool IMAPStore::isValidFolderName(const folder::path::component& /* name */) const { + return true; } -void IMAPStore::connect() -{ - if (isConnected()) - throw exceptions::already_connected(); +void IMAPStore::connect() { - m_connection = make_shared - (dynamicCast (shared_from_this()), getAuthenticator()); + if (isConnected()) { + throw exceptions::already_connected(); + } + + m_connection = make_shared ( + dynamicCast (shared_from_this()), getAuthenticator() + ); m_connection->connect(); } -bool IMAPStore::isConnected() const -{ - return (m_connection && m_connection->isConnected()); +bool IMAPStore::isConnected() const { + + return m_connection && m_connection->isConnected(); } -bool IMAPStore::isIMAPS() const -{ +bool IMAPStore::isIMAPS() const { + return m_isIMAPS; } -bool IMAPStore::isSecuredConnection() const -{ - if (m_connection == NULL) +bool IMAPStore::isSecuredConnection() const { + + if (!m_connection) { return false; + } return m_connection->isSecuredConnection(); } -shared_ptr IMAPStore::getConnectionInfos() const -{ - if (m_connection == NULL) +shared_ptr IMAPStore::getConnectionInfos() const { + + if (!m_connection) { return null; + } return m_connection->getConnectionInfos(); } -shared_ptr IMAPStore::getConnection() -{ +shared_ptr IMAPStore::getConnection() { + return m_connection; } -void IMAPStore::disconnect() -{ - if (!isConnected()) +void IMAPStore::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { + it != m_folders.end() ; ++it) { + (*it)->onStoreDisconnected(); } @@ -180,60 +198,65 @@ void IMAPStore::disconnect() } -void IMAPStore::noop() -{ - if (!isConnected()) +void IMAPStore::noop() { + + if (!isConnected()) { throw exceptions::not_connected(); + } IMAPCommand::NOOP()->send(m_connection); scoped_ptr resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> - resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) - { + resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { + throw exceptions::command_error("NOOP", resp->getErrorLog()); } for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { - if ((*it)->isOpen()) + it != m_folders.end() ; ++it) { + + if ((*it)->isOpen()) { (*it)->noop(); + } } } -shared_ptr IMAPStore::connection() -{ - return (m_connection); +shared_ptr IMAPStore::connection() { + + return m_connection; } -void IMAPStore::registerFolder(IMAPFolder* folder) -{ +void IMAPStore::registerFolder(IMAPFolder* folder) { + m_folders.push_back(folder); } -void IMAPStore::unregisterFolder(IMAPFolder* folder) -{ +void IMAPStore::unregisterFolder(IMAPFolder* folder) { + std::list ::iterator it = std::find(m_folders.begin(), m_folders.end(), folder); - if (it != m_folders.end()) m_folders.erase(it); + + if (it != m_folders.end()) { + m_folders.erase(it); + } } -int IMAPStore::getCapabilities() const -{ - return (CAPABILITY_CREATE_FOLDER | - CAPABILITY_RENAME_FOLDER | - CAPABILITY_ADD_MESSAGE | - CAPABILITY_COPY_MESSAGE | - CAPABILITY_DELETE_MESSAGE | - CAPABILITY_PARTIAL_FETCH | - CAPABILITY_MESSAGE_FLAGS | - CAPABILITY_EXTRACT_PART); +int IMAPStore::getCapabilities() const { + + return CAPABILITY_CREATE_FOLDER | + CAPABILITY_RENAME_FOLDER | + CAPABILITY_ADD_MESSAGE | + CAPABILITY_COPY_MESSAGE | + CAPABILITY_DELETE_MESSAGE | + CAPABILITY_PARTIAL_FETCH | + CAPABILITY_MESSAGE_FLAGS | + CAPABILITY_EXTRACT_PART; } @@ -243,14 +266,14 @@ int IMAPStore::getCapabilities() const IMAPServiceInfos IMAPStore::sm_infos(false); -const serviceInfos& IMAPStore::getInfosInstance() -{ +const serviceInfos& IMAPStore::getInfosInstance() { + return sm_infos; } -const serviceInfos& IMAPStore::getInfos() const -{ +const serviceInfos& IMAPStore::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/imap/IMAPStore.hpp b/src/vmime/net/imap/IMAPStore.hpp index 80932af4..018c195e 100644 --- a/src/vmime/net/imap/IMAPStore.hpp +++ b/src/vmime/net/imap/IMAPStore.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,16 +51,20 @@ class IMAPFolder; /** IMAP store service. */ +class VMIME_EXPORT IMAPStore : public store { -class VMIME_EXPORT IMAPStore : public store -{ friend class IMAPFolder; friend class IMAPMessage; friend class IMAPConnection; public: - IMAPStore(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); + IMAPStore( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured = false + ); + ~IMAPStore(); const string getProtocolName() const; diff --git a/src/vmime/net/imap/IMAPTag.cpp b/src/vmime/net/imap/IMAPTag.cpp index 14d12788..69f48477 100644 --- a/src/vmime/net/imap/IMAPTag.cpp +++ b/src/vmime/net/imap/IMAPTag.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,70 +39,72 @@ const int IMAPTag::sm_maxNumber = 52 * 10 * 10 * 10; IMAPTag::IMAPTag(const int number) - : m_number(number) -{ + : m_number(number) { + m_tag.resize(4); generate(); } IMAPTag::IMAPTag(const IMAPTag& tag) - : object(), m_number(tag.m_number) -{ + : object(), + m_number(tag.m_number) { + m_tag.resize(4); generate(); } IMAPTag::IMAPTag() - : m_number(1) -{ + : m_number(1) { + m_tag.resize(4); generate(); } -IMAPTag& IMAPTag::operator++() -{ +IMAPTag& IMAPTag::operator++() { + ++m_number; - if (m_number >= sm_maxNumber) + if (m_number >= sm_maxNumber) { m_number = 1; + } generate(); - return (*this); + return *this; } -const IMAPTag IMAPTag::operator++(int) -{ +const IMAPTag IMAPTag::operator++(int) { + IMAPTag old(*this); operator++(); - return (old); + return old; } -int IMAPTag::maximumNumber() const -{ +int IMAPTag::maximumNumber() const { + return sm_maxNumber - 1; } -int IMAPTag::number() const -{ - return (m_number); +int IMAPTag::number() const { + + return m_number; } IMAPTag::operator string() const { - return (m_tag); + return m_tag; } -void IMAPTag::generate() -{ +void IMAPTag::generate() { + static const char prefixChars[53] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/src/vmime/net/imap/IMAPTag.hpp b/src/vmime/net/imap/IMAPTag.hpp index 430a3b10..d4292fde 100644 --- a/src/vmime/net/imap/IMAPTag.hpp +++ b/src/vmime/net/imap/IMAPTag.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,8 +39,8 @@ namespace net { namespace imap { -class VMIME_EXPORT IMAPTag : public object -{ +class VMIME_EXPORT IMAPTag : public object { + private: IMAPTag(const int number); diff --git a/src/vmime/net/imap/IMAPUtils.cpp b/src/vmime/net/imap/IMAPUtils.cpp index bffc2c78..353fc2da 100644 --- a/src/vmime/net/imap/IMAPUtils.cpp +++ b/src/vmime/net/imap/IMAPUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace imap { // static -const string IMAPUtils::quoteString(const string& text) -{ +const string IMAPUtils::quoteString(const string& text) { + // // ATOM_CHAR ::= // @@ -66,66 +66,70 @@ const string IMAPUtils::quoteString(const string& text) bool needQuoting = text.empty(); for (string::const_iterator it = text.begin() ; - !needQuoting && it != text.end() ; ++it) - { + !needQuoting && it != text.end() ; ++it) { + const unsigned char c = *it; - switch (c) - { - case '(': - case ')': - case '{': - case 0x20: // SPACE - case '%': - case '*': - case '"': - case '\\': + switch (c) { - needQuoting = true; - break; + case '(': + case ')': + case '{': + case 0x20: // SPACE + case '%': + case '*': + case '"': + case '\\': - default: - - if (c <= 0x1f || c >= 0x7f) needQuoting = true; - } + break; + + default: + + if (c <= 0x1f || c >= 0x7f) { + needQuoting = true; + } + } } - if (needQuoting) - { + if (needQuoting) { + string quoted; quoted.reserve((text.length() * 3) / 2 + 2); quoted += '"'; - for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) - { + for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) { + const unsigned char c = *it; - if (c == '\\' || c == '"') + if (c == '\\' || c == '"') { quoted += '\\'; + } quoted += c; } quoted += '"'; - return (quoted); - } - else - { - return (text); + return quoted; + + } else { + + return text; } } -const string IMAPUtils::pathToString - (const char hierarchySeparator, const folder::path& path) -{ +const string IMAPUtils::pathToString( + const char hierarchySeparator, + const folder::path& path +) { + string result; - for (size_t i = 0 ; i < path.getSize() ; ++i) - { + for (size_t i = 0 ; i < path.getSize() ; ++i) { + if (i > 0) result += hierarchySeparator; result += toModifiedUTF7(hierarchySeparator, path[i]); } @@ -134,33 +138,35 @@ const string IMAPUtils::pathToString } -const folder::path IMAPUtils::stringToPath - (const char hierarchySeparator, const string& str) -{ +const folder::path IMAPUtils::stringToPath( + const char hierarchySeparator, + const string& str +) { + folder::path result; string::const_iterator begin = str.begin(); - for (string::const_iterator it = str.begin() ; it != str.end() ; ++it) - { - if (*it == hierarchySeparator) - { + for (string::const_iterator it = str.begin() ; it != str.end() ; ++it) { + + if (*it == hierarchySeparator) { result /= fromModifiedUTF7(string(begin, it)); begin = it + 1; } } - if (begin != str.end()) - { + if (begin != str.end()) { result /= fromModifiedUTF7(string(begin, str.end())); } - return (result); + return result; } -const string IMAPUtils::toModifiedUTF7 - (const char hierarchySeparator, const folder::path::component& text) -{ +const string IMAPUtils::toModifiedUTF7( + const char hierarchySeparator, + const folder::path::component& text +) { + // We will replace the hierarchy separator with an equivalent // UTF-7 sequence, so we compute it here... const char base64alphabet[] = @@ -192,13 +198,13 @@ const string IMAPUtils::toModifiedUTF7 size_t remaining = cvt.length(); - for (size_t i = 0, len = cvt.length() ; i < len ; ) - { + for (size_t i = 0, len = cvt.length() ; i < len ; ) { + const unsigned char c = cvt[i]; // Replace hierarchy separator with an equivalent UTF-7 Base64 sequence - if (!base64 && c == hierarchySeparator) - { + if (!base64 && c == hierarchySeparator) { + out += "&" + hsUTF7 + "-"; ++i; @@ -209,72 +215,78 @@ const string IMAPUtils::toModifiedUTF7 size_t n = 0; int ch = 0; - if (c < 0x80) + if (c < 0x80) { ch = c, n = 0; - else if (c < 0xc2) + } else if (c < 0xc2) { return ""; - else if (c < 0xe0) + } else if (c < 0xe0) { ch = c & 0x1f, n = 1; - else if (c < 0xf0) + } else if (c < 0xf0) { ch = c & 0x0f, n = 2; - else if (c < 0xf8) + } else if (c < 0xf8) { ch = c & 0x07, n = 3; - else if (c < 0xfc) + } else if (c < 0xfc) { ch = c & 0x03, n = 4; - else if (c < 0xfe) + } else if (c < 0xfe) { ch = c & 0x01, n = 5; - else + } else { return ""; + } - if (n > remaining) + if (n > remaining) { return ""; // error + } ++i; --remaining; - for (size_t j = 0 ; j < n ; j++) - { - if ((cvt[i + j] & 0xc0) != 0x80) + for (size_t j = 0 ; j < n ; j++) { + + if ((cvt[i + j] & 0xc0) != 0x80) { return ""; // error + } ch = (ch << 6) | (cvt[i + j] & 0x3f); } - if (n > 1 && !(ch >> (n * 5 + 1))) + if (n > 1 && !(ch >> (n * 5 + 1))) { return ""; // error + } i += n; remaining -= n; - if (ch < 0x20 || ch >= 0x7f) - { - if (!base64) - { + if (ch < 0x20 || ch >= 0x7f) { + + if (!base64) { out += '&'; base64 = true; b = 0; k = 10; } - if (ch & ~0xffff) + if (ch & ~0xffff) { ch = 0xfffe; + } out += base64alphabet[b | ch >> k]; k -= 6; - for ( ; k >= 0 ; k -= 6) + for ( ; k >= 0 ; k -= 6) { out += base64alphabet[(ch >> k) & 0x3f]; + } b = (ch << (-k)) & 0x3f; k += 16; - } - else - { - if (base64) - { - if (k > 10) + + } else { + + if (base64) { + + if (k > 10) { out += base64alphabet[b]; + } out += '-'; base64 = false; @@ -282,15 +294,17 @@ const string IMAPUtils::toModifiedUTF7 out += static_cast (ch); - if (ch == '&') + if (ch == '&') { out += '-'; + } } } - if (base64) - { - if (k > 10) + if (base64) { + + if (k > 10) { out += base64alphabet[b]; + } out += '-'; } @@ -299,8 +313,8 @@ const string IMAPUtils::toModifiedUTF7 } -const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text) -{ +const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text) { + // Transcode from modified UTF-7 (RFC-2060). string out; out.reserve(text.length()); @@ -309,62 +323,57 @@ const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text) bool plusOutput = false; unsigned char prev = 0; - for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) - { + for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) { + const unsigned char c = *it; - switch (c) - { - // Start of Base64 sequence - case '&': - { - if (!inB64sequence) - { - inB64sequence = true; - plusOutput = false; + switch (c) { + + // Start of Base64 sequence + case '&': { + + if (!inB64sequence) { + inB64sequence = true; + plusOutput = false; + } else { + out += '&'; + } + + break; } - else - { - out += '&'; + // End of Base64 sequence (or "&-" --> "&") + case '-': { + + if (inB64sequence && prev == '&') { // special case "&-" --> "&" + out += '&'; + } else { + out += '-'; + } + + inB64sequence = false; + break; } + // ',' is used instead of '/' in modified Base64 + case ',': { - break; - } - // End of Base64 sequence (or "&-" --> "&") - case '-': - { - if (inB64sequence && prev == '&') // special case "&-" --> "&" - out += '&'; - else - out += '-'; + if (inB64sequence && !plusOutput) { + out += '+'; + plusOutput = true; + } - inB64sequence = false; - break; - } - // ',' is used instead of '/' in modified Base64 - case ',': - { - if (inB64sequence && !plusOutput) - { - out += '+'; - plusOutput = true; + out += (inB64sequence ? '/' : ','); + break; } + default: { - out += (inB64sequence ? '/' : ','); - break; - } - default: - { - if (inB64sequence && !plusOutput) - { - out += '+'; - plusOutput = true; + if (inB64sequence && !plusOutput) { + out += '+'; + plusOutput = true; + } + + out += c; + break; } - - out += c; - break; - } - } prev = c; @@ -372,94 +381,96 @@ const folder::path::component IMAPUtils::fromModifiedUTF7(const string& text) // Store it as UTF-8 by default string cvt; - charset::convert(out, cvt, - charset(charsets::UTF_7), charset(charsets::UTF_8)); + charset::convert(out, cvt, charset(charsets::UTF_7), charset(charsets::UTF_8)); - return (folder::path::component(cvt, charset(charsets::UTF_8))); + return folder::path::component(cvt, charset(charsets::UTF_8)); } // static -void IMAPUtils::mailboxFlagsToFolderAttributes - (const shared_ptr & cnt, const IMAPParser::mailbox_flag_list* list, - folderAttributes& attribs) -{ +void IMAPUtils::mailboxFlagsToFolderAttributes( + const shared_ptr & cnt, + const IMAPParser::mailbox_flag_list* list, + folderAttributes& attribs +) { + int specialUse = folderAttributes::SPECIALUSE_NONE; int type = folderAttributes::TYPE_CONTAINS_MESSAGES | folderAttributes::TYPE_CONTAINS_FOLDERS; int flags = 0; // If CHILDREN extension (RFC-3348) is not supported, assume folder has children // as we have no hint about it - if (!cnt->hasCapability("CHILDREN")) + if (!cnt->hasCapability("CHILDREN")) { flags |= folderAttributes::FLAG_HAS_CHILDREN; + } const std::vector & mailboxFlags = list->flags(); for (std::vector ::const_iterator it = mailboxFlags.begin() ; - it != mailboxFlags.end() ; ++it) - { - switch ((*it)->type()) - { - case IMAPParser::mailbox_flag::NOSELECT: + it != mailboxFlags.end() ; ++it) { - type &= ~folderAttributes::TYPE_CONTAINS_MESSAGES; - flags |= folderAttributes::FLAG_NO_OPEN; - break; + switch ((*it)->type()) { - case IMAPParser::mailbox_flag::NOINFERIORS: - case IMAPParser::mailbox_flag::HASNOCHILDREN: + case IMAPParser::mailbox_flag::NOSELECT: - flags &= ~folderAttributes::FLAG_HAS_CHILDREN; - break; + type &= ~folderAttributes::TYPE_CONTAINS_MESSAGES; + flags |= folderAttributes::FLAG_NO_OPEN; + break; - case IMAPParser::mailbox_flag::HASCHILDREN: + case IMAPParser::mailbox_flag::NOINFERIORS: + case IMAPParser::mailbox_flag::HASNOCHILDREN: - flags |= folderAttributes::FLAG_HAS_CHILDREN; - break; + flags &= ~folderAttributes::FLAG_HAS_CHILDREN; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_ALL: + case IMAPParser::mailbox_flag::HASCHILDREN: - specialUse = folderAttributes::SPECIALUSE_ALL; - break; + flags |= folderAttributes::FLAG_HAS_CHILDREN; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_ARCHIVE: + case IMAPParser::mailbox_flag::SPECIALUSE_ALL: - specialUse = folderAttributes::SPECIALUSE_ARCHIVE; - break; + specialUse = folderAttributes::SPECIALUSE_ALL; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_DRAFTS: + case IMAPParser::mailbox_flag::SPECIALUSE_ARCHIVE: - specialUse = folderAttributes::SPECIALUSE_DRAFTS; - break; + specialUse = folderAttributes::SPECIALUSE_ARCHIVE; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_FLAGGED: + case IMAPParser::mailbox_flag::SPECIALUSE_DRAFTS: - specialUse = folderAttributes::SPECIALUSE_FLAGGED; - break; + specialUse = folderAttributes::SPECIALUSE_DRAFTS; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_JUNK: + case IMAPParser::mailbox_flag::SPECIALUSE_FLAGGED: - specialUse = folderAttributes::SPECIALUSE_JUNK; - break; + specialUse = folderAttributes::SPECIALUSE_FLAGGED; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_SENT: + case IMAPParser::mailbox_flag::SPECIALUSE_JUNK: - specialUse = folderAttributes::SPECIALUSE_SENT; - break; + specialUse = folderAttributes::SPECIALUSE_JUNK; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_TRASH: + case IMAPParser::mailbox_flag::SPECIALUSE_SENT: - specialUse = folderAttributes::SPECIALUSE_TRASH; - break; + specialUse = folderAttributes::SPECIALUSE_SENT; + break; - case IMAPParser::mailbox_flag::SPECIALUSE_IMPORTANT: + case IMAPParser::mailbox_flag::SPECIALUSE_TRASH: - specialUse = folderAttributes::SPECIALUSE_IMPORTANT; - break; + specialUse = folderAttributes::SPECIALUSE_TRASH; + break; - default: + case IMAPParser::mailbox_flag::SPECIALUSE_IMPORTANT: - break; + specialUse = folderAttributes::SPECIALUSE_IMPORTANT; + break; + + default: + + break; } } @@ -469,49 +480,60 @@ void IMAPUtils::mailboxFlagsToFolderAttributes } -int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list) -{ +int IMAPUtils::messageFlagsFromFlags(const IMAPParser::flag_list* list) { + const std::vector & flagList = list->flags(); int flags = 0; for (std::vector ::const_iterator - it = flagList.begin() ; it != flagList.end() ; ++it) - { - switch ((*it)->type()) - { - case IMAPParser::flag::ANSWERED: - flags |= message::FLAG_REPLIED; - break; - case IMAPParser::flag::FLAGGED: - flags |= message::FLAG_MARKED; - break; - case IMAPParser::flag::DELETED: - flags |= message::FLAG_DELETED; - break; - case IMAPParser::flag::SEEN: - flags |= message::FLAG_SEEN; - break; - case IMAPParser::flag::DRAFT: - flags |= message::FLAG_DRAFT; - break; + it = flagList.begin() ; it != flagList.end() ; ++it) { - default: - //case IMAPParser::flag::UNKNOWN: - break; + switch ((*it)->type()) { + + case IMAPParser::flag::ANSWERED: + + flags |= message::FLAG_REPLIED; + break; + + case IMAPParser::flag::FLAGGED: + + flags |= message::FLAG_MARKED; + break; + + case IMAPParser::flag::DELETED: + + flags |= message::FLAG_DELETED; + break; + + case IMAPParser::flag::SEEN: + + flags |= message::FLAG_SEEN; + break; + + case IMAPParser::flag::DRAFT: + + flags |= message::FLAG_DRAFT; + break; + + default: + //case IMAPParser::flag::UNKNOWN: + + break; } } - return (flags); + return flags; } // static -const std::vector IMAPUtils::messageFlagList(const int flags) -{ +const std::vector IMAPUtils::messageFlagList(const int flags) { + std::vector flagList; - if (flags == -1) + if (flags == -1) { return flagList; // default flags + } if (flags & message::FLAG_REPLIED) flagList.push_back("\\Answered"); if (flags & message::FLAG_MARKED) flagList.push_back("\\Flagged"); @@ -524,8 +546,8 @@ const std::vector IMAPUtils::messageFlagList(const int flags) // static -const string IMAPUtils::dateTime(const vmime::datetime& date) -{ +const string IMAPUtils::dateTime(const vmime::datetime& date) { + std::ostringstream res; res.imbue(std::locale::classic()); @@ -545,9 +567,10 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) res << '-'; - static const char* monthNames[12] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + static const char* monthNames[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; res << monthNames[std::min(std::max(date.getMonth() - 1, 0), 11)]; @@ -587,15 +610,17 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) res << '"'; - - return (res.str()); + return res.str(); } // static -shared_ptr IMAPUtils::buildFetchCommand - (const shared_ptr & cnt, const messageSet& msgs, const fetchAttributes& options) -{ +shared_ptr IMAPUtils::buildFetchCommand( + const shared_ptr & cnt, + const messageSet& msgs, + const fetchAttributes& options +) { + // Example: // C: A654 FETCH 2:4 (FLAGS BODY[HEADER.FIELDS (DATE FROM)]) // S: * 2 FETCH .... @@ -605,38 +630,45 @@ shared_ptr IMAPUtils::buildFetchCommand std::vector items; - if (options.has(fetchAttributes::SIZE)) + if (options.has(fetchAttributes::SIZE)) { items.push_back("RFC822.SIZE"); + } - if (options.has(fetchAttributes::FLAGS)) + if (options.has(fetchAttributes::FLAGS)) { items.push_back("FLAGS"); + } - if (options.has(fetchAttributes::STRUCTURE)) + if (options.has(fetchAttributes::STRUCTURE)) { items.push_back("BODYSTRUCTURE"); + } + + if (options.has(fetchAttributes::UID)) { - if (options.has(fetchAttributes::UID)) - { items.push_back("UID"); // Also fetch MODSEQ if CONDSTORE is supported - if (cnt && cnt->hasCapability("CONDSTORE") && !cnt->isMODSEQDisabled()) + if (cnt && cnt->hasCapability("CONDSTORE") && !cnt->isMODSEQDisabled()) { items.push_back("MODSEQ"); + } } - if (options.has(fetchAttributes::FULL_HEADER)) + if (options.has(fetchAttributes::FULL_HEADER)) { + items.push_back("RFC822.HEADER"); - else - { - if (options.has(fetchAttributes::ENVELOPE)) + + } else { + + if (options.has(fetchAttributes::ENVELOPE)) { items.push_back("ENVELOPE"); + } std::vector headerFields; - if (options.has(fetchAttributes::CONTENT_INFO)) + if (options.has(fetchAttributes::CONTENT_INFO)) { headerFields.push_back("CONTENT_TYPE"); + } - if (options.has(fetchAttributes::IMPORTANCE)) - { + if (options.has(fetchAttributes::IMPORTANCE)) { headerFields.push_back("IMPORTANCE"); headerFields.push_back("X-PRIORITY"); } @@ -645,15 +677,16 @@ shared_ptr IMAPUtils::buildFetchCommand const std::vector customHeaderFields = options.getHeaderFields(); std::copy(customHeaderFields.begin(), customHeaderFields.end(), std::back_inserter(headerFields)); - if (!headerFields.empty()) - { + if (!headerFields.empty()) { + string list; for (std::vector ::iterator it = headerFields.begin() ; - it != headerFields.end() ; ++it) - { - if (it != headerFields.begin()) + it != headerFields.end() ; ++it) { + + if (it != headerFields.begin()) { list += " "; + } list += *it; } @@ -667,12 +700,14 @@ shared_ptr IMAPUtils::buildFetchCommand // static -void IMAPUtils::convertAddressList - (const IMAPParser::address_list& src, mailboxList& dest) -{ +void IMAPUtils::convertAddressList( + const IMAPParser::address_list& src, + mailboxList& dest +) { + for (std::vector ::const_iterator - it = src.addresses().begin() ; it != src.addresses().end() ; ++it) - { + it = src.addresses().begin() ; it != src.addresses().end() ; ++it) { + const IMAPParser::address& addr = **it; text name; @@ -687,48 +722,52 @@ void IMAPUtils::convertAddressList -class IMAPUIDMessageSetEnumerator : public messageSetEnumerator -{ +class IMAPUIDMessageSetEnumerator : public messageSetEnumerator { + public: IMAPUIDMessageSetEnumerator() - : m_first(true) - { + : m_first(true) { + m_oss.imbue(std::locale::classic()); } - void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) - { - if (!m_first) - m_oss << ","; + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { - if (range.getFirst() == range.getLast()) + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { m_oss << range.getFirst(); - else if (range.getLast() == size_t(-1)) + } else if (range.getLast() == size_t(-1)) { m_oss << range.getFirst() << ":*"; - else + } else { m_oss << range.getFirst() << ":" << range.getLast(); + } m_first = false; } - void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) - { - if (!m_first) - m_oss << ","; + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) { - if (range.getFirst() == range.getLast()) + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { m_oss << range.getFirst(); - else if (range.getLast() == size_t(-1)) + } else if (range.getLast() == size_t(-1)) { m_oss << range.getFirst() << ":*"; - else + } else { m_oss << range.getFirst() << ":" << range.getLast(); + } m_first = false; } - const std::string str() const - { + const std::string str() const { + return m_oss.str(); } @@ -739,23 +778,24 @@ private: }; -class IMAPMessageSetEnumerator : public messageSetEnumerator -{ +class IMAPMessageSetEnumerator : public messageSetEnumerator { + public: - void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) - { - for (size_t i = range.getFirst(), last = range.getLast() ; i <= last ; ++i) + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { + + for (size_t i = range.getFirst(), last = range.getLast() ; i <= last ; ++i) { m_list.push_back(i); + } } - void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) - { + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) { + // Not used } - const std::vector & list() const - { + const std::vector & list() const { + return m_list; } @@ -767,8 +807,8 @@ public: // static -const string IMAPUtils::messageSetToSequenceSet(const messageSet& msgs) -{ +const string IMAPUtils::messageSetToSequenceSet(const messageSet& msgs) { + IMAPUIDMessageSetEnumerator en; msgs.enumerate(en); @@ -777,22 +817,28 @@ const string IMAPUtils::messageSetToSequenceSet(const messageSet& msgs) // static -messageSet IMAPUtils::buildMessageSet(const IMAPParser::uid_set* uidSet) -{ +messageSet IMAPUtils::buildMessageSet(const IMAPParser::uid_set* uidSet) { + messageSet set = messageSet::empty(); - for ( ; uidSet ; uidSet = uidSet->next_uid_set()) - { - if (uidSet->uid_range()) - { - set.addRange(UIDMessageRange - (message::uid(uidSet->uid_range()->uniqueid1()->value()), - message::uid(uidSet->uid_range()->uniqueid2()->value()))); - } - else - { - set.addRange(UIDMessageRange - (message::uid(uidSet->uniqueid()->value()))); + for ( ; uidSet ; uidSet = uidSet->next_uid_set()) { + + if (uidSet->uid_range()) { + + set.addRange( + UIDMessageRange( + message::uid(uidSet->uid_range()->uniqueid1()->value()), + message::uid(uidSet->uid_range()->uniqueid2()->value()) + ) + ); + + } else { + + set.addRange( + UIDMessageRange( + message::uid(uidSet->uniqueid()->value()) + ) + ); } } diff --git a/src/vmime/net/imap/IMAPUtils.hpp b/src/vmime/net/imap/IMAPUtils.hpp index a7daf736..957ff846 100644 --- a/src/vmime/net/imap/IMAPUtils.hpp +++ b/src/vmime/net/imap/IMAPUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/imap/imap.hpp b/src/vmime/net/imap/imap.hpp index 5e10619a..f25baa4b 100644 --- a/src/vmime/net/imap/imap.hpp +++ b/src/vmime/net/imap/imap.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/maildir/format/courierMaildirFormat.cpp b/src/vmime/net/maildir/format/courierMaildirFormat.cpp index 78753796..e6119490 100644 --- a/src/vmime/net/maildir/format/courierMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/courierMaildirFormat.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,33 +42,38 @@ namespace format { courierMaildirFormat::courierMaildirFormat(const shared_ptr & ctx) - : maildirFormat(ctx) -{ + : maildirFormat(ctx) { + } -const string courierMaildirFormat::getName() const -{ +const string courierMaildirFormat::getName() const { + return "courier"; } -void courierMaildirFormat::createFolder(const folder::path& path) -{ +void courierMaildirFormat::createFolder(const folder::path& path) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY))) + if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY))) { throw exceptions::invalid_folder_name(); + } - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + ); - shared_ptr newDir = fsf->create - (folderPathToFileSystemPath(path, NEW_DIRECTORY)); - shared_ptr tmpDir = fsf->create - (folderPathToFileSystemPath(path, TMP_DIRECTORY)); - shared_ptr curDir = fsf->create - (folderPathToFileSystemPath(path, CUR_DIRECTORY)); + shared_ptr newDir = fsf->create( + folderPathToFileSystemPath(path, NEW_DIRECTORY) + ); + shared_ptr tmpDir = fsf->create( + folderPathToFileSystemPath(path, TMP_DIRECTORY) + ); + shared_ptr curDir = fsf->create( + folderPathToFileSystemPath(path, CUR_DIRECTORY) + ); rootDir->createDirectory(true); @@ -76,40 +81,45 @@ void courierMaildirFormat::createFolder(const folder::path& path) tmpDir->createDirectory(false); curDir->createDirectory(false); - shared_ptr maildirFile = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY) - / utility::file::path::component("maildirfolder")); + shared_ptr maildirFile = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + / utility::file::path::component("maildirfolder") + ); maildirFile->createFile(); } -void courierMaildirFormat::destroyFolder(const folder::path& path) -{ +void courierMaildirFormat::destroyFolder(const folder::path& path) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); // Recursively delete directories of subfolders const std::vector folders = listFolders(path, true); - for (std::vector ::size_type i = 0, n = folders.size() ; i < n ; ++i) - { - maildirUtils::recursiveFSDelete(fsf->create - (folderPathToFileSystemPath(folders[i], ROOT_DIRECTORY))); + for (std::vector ::size_type i = 0, n = folders.size() ; i < n ; ++i) { + + maildirUtils::recursiveFSDelete( + fsf->create(folderPathToFileSystemPath(folders[i], ROOT_DIRECTORY)) + ); } // Recursively delete the directory of this folder - maildirUtils::recursiveFSDelete(fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY))); + maildirUtils::recursiveFSDelete( + fsf->create(folderPathToFileSystemPath(path, ROOT_DIRECTORY)) + ); } -void courierMaildirFormat::renameFolder - (const folder::path& oldPath, const folder::path& newPath) -{ +void courierMaildirFormat::renameFolder( + const folder::path& oldPath, + const folder::path& newPath +) { + const std::vector folders = listFolders(oldPath, true); - for (std::vector ::size_type i = 0, n = folders.size() ; i < n ; ++i) - { + for (std::vector ::size_type i = 0, n = folders.size() ; i < n ; ++i) { + const folder::path folderOldPath = folders[i]; folder::path folderNewPath = folderOldPath; @@ -122,9 +132,11 @@ void courierMaildirFormat::renameFolder } -void courierMaildirFormat::renameFolderImpl - (const folder::path& oldPath, const folder::path& newPath) -{ +void courierMaildirFormat::renameFolderImpl( + const folder::path& oldPath, + const folder::path& newPath +) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); const utility::file::path oldFSPath = @@ -138,98 +150,109 @@ void courierMaildirFormat::renameFolderImpl } -bool courierMaildirFormat::folderExists(const folder::path& path) const -{ +bool courierMaildirFormat::folderExists(const folder::path& path) const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + ); - shared_ptr newDir = fsf->create - (folderPathToFileSystemPath(path, NEW_DIRECTORY)); - shared_ptr tmpDir = fsf->create - (folderPathToFileSystemPath(path, TMP_DIRECTORY)); - shared_ptr curDir = fsf->create - (folderPathToFileSystemPath(path, CUR_DIRECTORY)); + shared_ptr newDir = fsf->create( + folderPathToFileSystemPath(path, NEW_DIRECTORY) + ); + shared_ptr tmpDir = fsf->create( + folderPathToFileSystemPath(path, TMP_DIRECTORY) + ); + shared_ptr curDir = fsf->create( + folderPathToFileSystemPath(path, CUR_DIRECTORY) + ); - shared_ptr maildirFile = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY) - / utility::file::path::component("maildirfolder")); + shared_ptr maildirFile = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + / utility::file::path::component("maildirfolder") + ); bool exists = rootDir->exists() && rootDir->isDirectory() && - newDir->exists() && newDir->isDirectory() && - tmpDir->exists() && tmpDir->isDirectory() && - curDir->exists() && curDir->isDirectory(); + newDir->exists() && newDir->isDirectory() && + tmpDir->exists() && tmpDir->isDirectory() && + curDir->exists() && curDir->isDirectory(); // If this is not the root folder, then a file named "maildirfolder" // must also be present in the directory - if (!path.isRoot()) + if (!path.isRoot()) { exists = exists && maildirFile->exists() && maildirFile->isFile(); + } return exists; } -bool courierMaildirFormat::folderHasSubfolders(const folder::path& path) const -{ +bool courierMaildirFormat::folderHasSubfolders(const folder::path& path) const { + std::vector dirs; return listDirectories(path, dirs, true); } -const utility::file::path courierMaildirFormat::folderPathToFileSystemPath - (const folder::path& path, const DirectoryType type) const -{ +const utility::file::path courierMaildirFormat::folderPathToFileSystemPath( + const folder::path& path, + const DirectoryType type +) const { + // Virtual folder "/MyFolder/SubFolder" corresponds to physical // directory "[store root]/.MyFolder.SubFolder" utility::file::path fsPath = getContext()->getStore()->getFileSystemPath(); - if (!path.isRoot()) - { + if (!path.isRoot()) { + string folderComp; - for (size_t i = 0, n = path.getSize() ; i < n ; ++i) + for (size_t i = 0, n = path.getSize() ; i < n ; ++i) { folderComp += "." + toModifiedUTF7(path[i]); + } fsPath /= utility::file::path::component(folderComp); } // Last component - switch (type) - { - case ROOT_DIRECTORY: + switch (type) { - // Nothing to add - break; + case ROOT_DIRECTORY: - case NEW_DIRECTORY: + // Nothing to add + break; - fsPath /= NEW_DIR; - break; + case NEW_DIRECTORY: - case CUR_DIRECTORY: + fsPath /= NEW_DIR; + break; - fsPath /= CUR_DIR; - break; + case CUR_DIRECTORY: - case TMP_DIRECTORY: + fsPath /= CUR_DIR; + break; - fsPath /= TMP_DIR; - break; + case TMP_DIRECTORY: - case CONTAINER_DIRECTORY: + fsPath /= TMP_DIR; + break; - // Not used - break; + case CONTAINER_DIRECTORY: + + // Not used + break; } return fsPath; } -const std::vector courierMaildirFormat::listFolders - (const folder::path& root, const bool recursive) const -{ +const std::vector courierMaildirFormat::listFolders( + const folder::path& root, + const bool recursive +) const { + // First, list directories std::vector dirs; listDirectories(root, dirs, false); @@ -237,69 +260,75 @@ const std::vector courierMaildirFormat::listFolders // Then, map directories to folders std::vector folders; - for (std::vector ::size_type i = 0, n = dirs.size() ; i < n ; ++i) - { + for (std::vector ::size_type i = 0, n = dirs.size() ; i < n ; ++i) { + const string dir = dirs[i].substr(1) + "."; folder::path path; for (size_t pos = dir.find("."), prev = 0 ; - pos != string::npos ; prev = pos + 1, pos = dir.find(".", pos + 1)) - { + pos != string::npos ; prev = pos + 1, pos = dir.find(".", pos + 1)) { + const string comp = dir.substr(prev, pos - prev); path /= fromModifiedUTF7(comp); } - if (recursive || path.getSize() == root.getSize() + 1) + if (recursive || path.getSize() == root.getSize() + 1) { folders.push_back(path); + } } return folders; } -bool courierMaildirFormat::listDirectories(const folder::path& root, - std::vector & dirs, const bool onlyTestForExistence) const -{ +bool courierMaildirFormat::listDirectories( + const folder::path& root, + std::vector & dirs, + const bool onlyTestForExistence +) const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (getContext()->getStore()->getFileSystemPath()); + shared_ptr rootDir = fsf->create( + getContext()->getStore()->getFileSystemPath() + ); + + if (rootDir->exists()) { - if (rootDir->exists()) - { // To speed up things, and if we are not searching in root folder, // search for directories with a common prefix string base; - if (!root.isRoot()) - { - for (size_t i = 0, n = root.getSize() ; i < n ; ++i) + if (!root.isRoot()) { + for (size_t i = 0, n = root.getSize() ; i < n ; ++i) { base += "." + toModifiedUTF7(root[i]); + } } // Enumerate directories shared_ptr it = rootDir->getFiles(); - while (it->hasMoreElements()) - { + while (it->hasMoreElements()) { + shared_ptr file = it->nextElement(); - if (isSubfolderDirectory(*file)) - { + if (isSubfolderDirectory(*file)) { + const string dir = file->getFullPath().getLastComponent().getBuffer(); - if (base.empty() || (dir.length() > base.length() && dir.substr(0, base.length()) == base)) - { + if (base.empty() || (dir.length() > base.length() && dir.substr(0, base.length()) == base)) { + dirs.push_back(dir); - if (onlyTestForExistence) + if (onlyTestForExistence) { return true; + } } } } - } - else - { + + } else { + // No sub-folder } @@ -310,13 +339,13 @@ bool courierMaildirFormat::listDirectories(const folder::path& root, // static -bool courierMaildirFormat::isSubfolderDirectory(const utility::file& file) -{ +bool courierMaildirFormat::isSubfolderDirectory(const utility::file& file) { + // A directory which names starts with '.' may be a subfolder if (file.isDirectory() && file.getFullPath().getLastComponent().getBuffer().length() >= 1 && - file.getFullPath().getLastComponent().getBuffer()[0] == '.') - { + file.getFullPath().getLastComponent().getBuffer()[0] == '.') { + return true; } @@ -325,8 +354,8 @@ bool courierMaildirFormat::isSubfolderDirectory(const utility::file& file) // static -const string courierMaildirFormat::toModifiedUTF7(const folder::path::component& text) -{ +const string courierMaildirFormat::toModifiedUTF7(const folder::path::component& text) { + // From http://www.courier-mta.org/?maildir.html: // // Folder names can contain any Unicode character, except for control @@ -364,67 +393,65 @@ const string courierMaildirFormat::toModifiedUTF7(const folder::path::component& bool inB64sequence = false; - for (string::const_iterator it = cvt.begin() ; it != cvt.end() ; ++it) - { + for (string::const_iterator it = cvt.begin() ; it != cvt.end() ; ++it) { + const unsigned char c = *it; - switch (c) - { - // Beginning of Base64 sequence: replace '+' with '&' - case '+': - { - if (!inB64sequence) - { - inB64sequence = true; - out += '&'; + switch (c) { + + // Beginning of Base64 sequence: replace '+' with '&' + case '+': { + + if (!inB64sequence) { + inB64sequence = true; + out += '&'; + } else { + out += '+'; + } + + break; } - else - { - out += '+'; + // End of Base64 sequence + case '-': { + + inB64sequence = false; + out += '-'; + break; } + // ',' is used instead of '/' in modified Base64, + // and simply UTF7-encoded out of a Base64 sequence + case '/': { - break; - } - // End of Base64 sequence - case '-': - { - inB64sequence = false; - out += '-'; - break; - } - // ',' is used instead of '/' in modified Base64, - // and simply UTF7-encoded out of a Base64 sequence - case '/': - { - if (inB64sequence) - out += ','; - else - out += "&Lw-"; + if (inB64sequence) { + out += ','; + } else { + out += "&Lw-"; + } - break; - } - // Encode period (should not happen in a Base64 sequence) - case '.': - { - out += "&Lg-"; - break; - } - // '&' (0x26) is represented by the two-octet sequence "&-" - case '&': - { - if (!inB64sequence) - out += "&-"; - else - out += '&'; + break; + } + // Encode period (should not happen in a Base64 sequence) + case '.': { - break; - } - default: - { - out += c; - break; - } + out += "&Lg-"; + break; + } + // '&' (0x26) is represented by the two-octet sequence "&-" + case '&': { + if (!inB64sequence) { + out += "&-"; + } else { + out += '&'; + } + + break; + } + default: { + + out += c; + break; + } } } @@ -433,8 +460,8 @@ const string courierMaildirFormat::toModifiedUTF7(const folder::path::component& // static -const folder::path::component courierMaildirFormat::fromModifiedUTF7(const string& text) -{ +const folder::path::component courierMaildirFormat::fromModifiedUTF7(const string& text) { + // Transcode from modified UTF-7 string out; out.reserve(text.length()); @@ -442,49 +469,47 @@ const folder::path::component courierMaildirFormat::fromModifiedUTF7(const strin bool inB64sequence = false; unsigned char prev = 0; - for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) - { + for (string::const_iterator it = text.begin() ; it != text.end() ; ++it) { + const unsigned char c = *it; - switch (c) - { - // Start of Base64 sequence - case '&': - { - if (!inB64sequence) - { - inB64sequence = true; - out += '+'; - } - else - { - out += '&'; - } + switch (c) { - break; - } - // End of Base64 sequence (or "&-" --> "&") - case '-': - { - if (inB64sequence && prev == '&') - out += '&'; - else - out += '-'; + // Start of Base64 sequence + case '&': { - inB64sequence = false; - break; - } - // ',' is used instead of '/' in modified Base64 - case ',': - { - out += (inB64sequence ? '/' : ','); - break; - } - default: - { - out += c; - break; - } + if (!inB64sequence) { + inB64sequence = true; + out += '+'; + } else { + out += '&'; + } + + break; + } + // End of Base64 sequence (or "&-" --> "&") + case '-': { + + if (inB64sequence && prev == '&') { + out += '&'; + } else { + out += '-'; + } + + inB64sequence = false; + break; + } + // ',' is used instead of '/' in modified Base64 + case ',': { + + out += (inB64sequence ? '/' : ','); + break; + } + default: { + + out += c; + break; + } } @@ -493,37 +518,39 @@ const folder::path::component courierMaildirFormat::fromModifiedUTF7(const strin // Store it as UTF-8 by default string cvt; - charset::convert(out, cvt, - charset(charsets::UTF_7), charset(charsets::UTF_8)); + charset::convert(out, cvt, charset(charsets::UTF_7), charset(charsets::UTF_8)); - return (folder::path::component(cvt, charset(charsets::UTF_8))); + return folder::path::component(cvt, charset(charsets::UTF_8)); } -bool courierMaildirFormat::supports() const -{ +bool courierMaildirFormat::supports() const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (getContext()->getStore()->getFileSystemPath()); + shared_ptr rootDir = fsf->create( + getContext()->getStore()->getFileSystemPath() + ); + + if (rootDir->exists()) { - if (rootDir->exists()) - { // Try to find a file named "maildirfolder", which indicates // the Maildir is in Courier format shared_ptr it = rootDir->getFiles(); - while (it->hasMoreElements()) - { + while (it->hasMoreElements()) { + shared_ptr file = it->nextElement(); - if (isSubfolderDirectory(*file)) - { - shared_ptr folderFile = fsf->create - (file->getFullPath() / utility::file::path::component("maildirfolder")); + if (isSubfolderDirectory(*file)) { - if (folderFile->exists() && folderFile->isFile()) + shared_ptr folderFile = fsf->create( + file->getFullPath() / utility::file::path::component("maildirfolder") + ); + + if (folderFile->exists() && folderFile->isFile()) { return true; + } } } } diff --git a/src/vmime/net/maildir/format/courierMaildirFormat.hpp b/src/vmime/net/maildir/format/courierMaildirFormat.hpp index 6b6841e2..7db1a834 100644 --- a/src/vmime/net/maildir/format/courierMaildirFormat.hpp +++ b/src/vmime/net/maildir/format/courierMaildirFormat.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,9 +42,8 @@ namespace format { /** Reads Courier/QMail Maildir format. */ +class VMIME_EXPORT courierMaildirFormat : public maildirFormat { -class VMIME_EXPORT courierMaildirFormat : public maildirFormat -{ public: courierMaildirFormat(const shared_ptr & ctx); @@ -68,11 +67,15 @@ public: bool folderExists(const folder::path& path) const; bool folderHasSubfolders(const folder::path& path) const; - const utility::file::path folderPathToFileSystemPath - (const folder::path& path, const DirectoryType type) const; + const utility::file::path folderPathToFileSystemPath( + const folder::path& path, + const DirectoryType type + ) const; - const std::vector listFolders - (const folder::path& root, const bool recursive) const; + const std::vector listFolders( + const folder::path& root, + const bool recursive + ) const; protected: @@ -104,8 +107,11 @@ protected: * @return true if at least one directory has been found, * false otherwise */ - bool listDirectories(const folder::path& root, - std::vector & dirs, const bool onlyTestForExistence) const; + bool listDirectories( + const folder::path& root, + std::vector & dirs, + const bool onlyTestForExistence + ) const; }; diff --git a/src/vmime/net/maildir/format/kmailMaildirFormat.cpp b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp index c52a2f45..4eb89e8b 100644 --- a/src/vmime/net/maildir/format/kmailMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,33 +42,38 @@ namespace format { kmailMaildirFormat::kmailMaildirFormat(const shared_ptr & ctx) - : maildirFormat(ctx) -{ + : maildirFormat(ctx) { + } -const string kmailMaildirFormat::getName() const -{ +const string kmailMaildirFormat::getName() const { + return "kmail"; } -void kmailMaildirFormat::createFolder(const folder::path& path) -{ +void kmailMaildirFormat::createFolder(const folder::path& path) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY))) + if (!fsf->isValidPath(folderPathToFileSystemPath(path, ROOT_DIRECTORY))) { throw exceptions::invalid_folder_name(); + } - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + ); - shared_ptr newDir = fsf->create - (folderPathToFileSystemPath(path, NEW_DIRECTORY)); - shared_ptr tmpDir = fsf->create - (folderPathToFileSystemPath(path, TMP_DIRECTORY)); - shared_ptr curDir = fsf->create - (folderPathToFileSystemPath(path, CUR_DIRECTORY)); + shared_ptr newDir = fsf->create( + folderPathToFileSystemPath(path, NEW_DIRECTORY) + ); + shared_ptr tmpDir = fsf->create( + folderPathToFileSystemPath(path, TMP_DIRECTORY) + ); + shared_ptr curDir = fsf->create( + folderPathToFileSystemPath(path, CUR_DIRECTORY) + ); rootDir->createDirectory(true); @@ -78,32 +83,38 @@ void kmailMaildirFormat::createFolder(const folder::path& path) } -void kmailMaildirFormat::destroyFolder(const folder::path& path) -{ +void kmailMaildirFormat::destroyFolder(const folder::path& path) { + // Delete 'folder' and '.folder.directory' directories shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - maildirUtils::recursiveFSDelete(fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY))); // root + maildirUtils::recursiveFSDelete( + fsf->create(folderPathToFileSystemPath(path, ROOT_DIRECTORY)) // root + ); - maildirUtils::recursiveFSDelete(fsf->create - (folderPathToFileSystemPath(path, CONTAINER_DIRECTORY))); // container + maildirUtils::recursiveFSDelete( + fsf->create(folderPathToFileSystemPath(path, CONTAINER_DIRECTORY)) // container + ); } -bool kmailMaildirFormat::folderExists(const folder::path& path) const -{ +bool kmailMaildirFormat::folderExists(const folder::path& path) const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(path, ROOT_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(path, ROOT_DIRECTORY) + ); - shared_ptr newDir = fsf->create - (folderPathToFileSystemPath(path, NEW_DIRECTORY)); - shared_ptr tmpDir = fsf->create - (folderPathToFileSystemPath(path, TMP_DIRECTORY)); - shared_ptr curDir = fsf->create - (folderPathToFileSystemPath(path, CUR_DIRECTORY)); + shared_ptr newDir = fsf->create( + folderPathToFileSystemPath(path, NEW_DIRECTORY) + ); + shared_ptr tmpDir = fsf->create( + folderPathToFileSystemPath(path, TMP_DIRECTORY) + ); + shared_ptr curDir = fsf->create( + folderPathToFileSystemPath(path, CUR_DIRECTORY) + ); return rootDir->exists() && rootDir->isDirectory() && newDir->exists() && newDir->isDirectory() && @@ -112,9 +123,11 @@ bool kmailMaildirFormat::folderExists(const folder::path& path) const } -const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath - (const folder::path& path, const DirectoryType type) const -{ +const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath( + const folder::path& path, + const DirectoryType type +) const { + // Root path utility::file::path fsPath = getContext()->getStore()->getFileSystemPath(); @@ -123,8 +136,8 @@ const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath ? pathSize : (pathSize >= 1 ? pathSize - 1 : 0)); // Parent folders - for (size_t i = 0 ; i < count ; ++i) - { + for (size_t i = 0 ; i < count ; ++i) { + utility::file::path::component comp(path[i]); // TODO: may not work with all encodings... @@ -134,36 +147,36 @@ const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath } // Last component - if (path.getSize() != 0 && type != CONTAINER_DIRECTORY) - { + if (path.getSize() != 0 && type != CONTAINER_DIRECTORY) { + fsPath /= path.getLastComponent(); - switch (type) - { - case ROOT_DIRECTORY: + switch (type) { - // Nothing to add - break; + case ROOT_DIRECTORY: - case NEW_DIRECTORY: + // Nothing to add + break; - fsPath /= NEW_DIR; - break; + case NEW_DIRECTORY: - case CUR_DIRECTORY: + fsPath /= NEW_DIR; + break; - fsPath /= CUR_DIR; - break; + case CUR_DIRECTORY: - case TMP_DIRECTORY: + fsPath /= CUR_DIR; + break; - fsPath /= TMP_DIR; - break; + case TMP_DIRECTORY: - case CONTAINER_DIRECTORY: + fsPath /= TMP_DIR; + break; - // Can't happen... - break; + case CONTAINER_DIRECTORY: + + // Can't happen... + break; } } @@ -171,9 +184,11 @@ const utility::file::path kmailMaildirFormat::folderPathToFileSystemPath } -const std::vector kmailMaildirFormat::listFolders - (const folder::path& root, const bool recursive) const -{ +const std::vector kmailMaildirFormat::listFolders( + const folder::path& root, + const bool recursive +) const { + std::vector list; listFoldersImpl(list, root, recursive); @@ -181,49 +196,53 @@ const std::vector kmailMaildirFormat::listFolders } -void kmailMaildirFormat::listFoldersImpl - (std::vector & list, const folder::path& root, const bool recursive) const -{ +void kmailMaildirFormat::listFoldersImpl( + std::vector & list, + const folder::path& root, + const bool recursive +) const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create(folderPathToFileSystemPath(root, - root.isEmpty() ? ROOT_DIRECTORY : CONTAINER_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(root, root.isEmpty() ? ROOT_DIRECTORY : CONTAINER_DIRECTORY) + ); + + if (rootDir->exists()) { - if (rootDir->exists()) - { shared_ptr it = rootDir->getFiles(); - while (it->hasMoreElements()) - { + while (it->hasMoreElements()) { + shared_ptr file = it->nextElement(); - if (isSubfolderDirectory(*file)) - { - const utility::path subPath = - root / file->getFullPath().getLastComponent(); + if (isSubfolderDirectory(*file)) { + + const utility::path subPath = root / file->getFullPath().getLastComponent(); list.push_back(subPath); - if (recursive) + if (recursive) { listFoldersImpl(list, subPath, true); + } } } - } - else - { + + } else { + // No sub-folder } } // static -bool kmailMaildirFormat::isSubfolderDirectory(const utility::file& file) -{ +bool kmailMaildirFormat::isSubfolderDirectory(const utility::file& file) { + // A directory which name does not start with '.' is listed as a sub-folder if (file.isDirectory() && file.getFullPath().getLastComponent().getBuffer().length() >= 1 && - file.getFullPath().getLastComponent().getBuffer()[0] != '.') - { + file.getFullPath().getLastComponent().getBuffer()[0] != '.') { + return true; } @@ -231,17 +250,19 @@ bool kmailMaildirFormat::isSubfolderDirectory(const utility::file& file) } -void kmailMaildirFormat::renameFolder(const folder::path& oldPath, const folder::path& newPath) -{ +void kmailMaildirFormat::renameFolder(const folder::path& oldPath, const folder::path& newPath) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY)); - shared_ptr contDir = fsf->create - (folderPathToFileSystemPath(oldPath, CONTAINER_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY) + ); + shared_ptr contDir = fsf->create( + folderPathToFileSystemPath(oldPath, CONTAINER_DIRECTORY) + ); + + try { - try - { const utility::file::path newRootPath = folderPathToFileSystemPath(newPath, ROOT_DIRECTORY); const utility::file::path newContPath = @@ -250,30 +271,24 @@ void kmailMaildirFormat::renameFolder(const folder::path& oldPath, const folder: rootDir->rename(newRootPath); // Container directory may not exist, so ignore error when trying to rename it - try - { + try { contDir->rename(newContPath); - } - catch (exceptions::filesystem_exception& e) - { + } catch (exceptions::filesystem_exception& e) { // Ignore } - } - catch (exceptions::filesystem_exception& e) - { + + } catch (exceptions::filesystem_exception& e) { + // Revert to old location const utility::file::path rootPath = folderPathToFileSystemPath(oldPath, ROOT_DIRECTORY); const utility::file::path contPath = folderPathToFileSystemPath(oldPath, CONTAINER_DIRECTORY); - try - { + try { rootDir->rename(rootPath); contDir->rename(contPath); - } - catch (exceptions::filesystem_exception& e) - { + } catch (exceptions::filesystem_exception& e) { // Ignore (not recoverable) } @@ -282,29 +297,31 @@ void kmailMaildirFormat::renameFolder(const folder::path& oldPath, const folder: } -bool kmailMaildirFormat::folderHasSubfolders(const folder::path& path) const -{ +bool kmailMaildirFormat::folderHasSubfolders(const folder::path& path) const { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - shared_ptr rootDir = fsf->create - (folderPathToFileSystemPath(path, CONTAINER_DIRECTORY)); + shared_ptr rootDir = fsf->create( + folderPathToFileSystemPath(path, CONTAINER_DIRECTORY) + ); shared_ptr it = rootDir->getFiles(); - while (it->hasMoreElements()) - { + while (it->hasMoreElements()) { + shared_ptr file = it->nextElement(); - if (isSubfolderDirectory(*file)) + if (isSubfolderDirectory(*file)) { return true; + } } return false; } -bool kmailMaildirFormat::supports() const -{ +bool kmailMaildirFormat::supports() const { + // This is the default return true; } diff --git a/src/vmime/net/maildir/format/kmailMaildirFormat.hpp b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp index 854e60be..26b557a3 100644 --- a/src/vmime/net/maildir/format/kmailMaildirFormat.hpp +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,9 +42,8 @@ namespace format { /** Reads KMail Maildir format. */ +class VMIME_EXPORT kmailMaildirFormat : public maildirFormat { -class VMIME_EXPORT kmailMaildirFormat : public maildirFormat -{ public: kmailMaildirFormat(const shared_ptr & ctx); @@ -68,11 +67,15 @@ public: bool folderExists(const folder::path& path) const; bool folderHasSubfolders(const folder::path& path) const; - const utility::file::path folderPathToFileSystemPath - (const folder::path& path, const DirectoryType type) const; + const utility::file::path folderPathToFileSystemPath( + const folder::path& path, + const DirectoryType type + ) const; - const std::vector listFolders - (const folder::path& root, const bool recursive) const; + const std::vector listFolders( + const folder::path& root, + const bool recursive + ) const; protected: @@ -81,8 +84,11 @@ protected: /** Recursive implementation of listFolders(). */ - void listFoldersImpl(std::vector & list, - const folder::path& root, const bool recursive) const; + void listFoldersImpl( + std::vector & list, + const folder::path& root, + const bool recursive + ) const; /** Test whether the specified file system directory corresponds to * a maildir subfolder. The name of the directory should not start diff --git a/src/vmime/net/maildir/maildir.hpp b/src/vmime/net/maildir/maildir.hpp index 42bbbea4..8835bf4c 100644 --- a/src/vmime/net/maildir/maildir.hpp +++ b/src/vmime/net/maildir/maildir.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/maildir/maildirFolder.cpp b/src/vmime/net/maildir/maildirFolder.cpp index fec1294b..8c02025b 100644 --- a/src/vmime/net/maildir/maildirFolder.cpp +++ b/src/vmime/net/maildir/maildirFolder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,93 +49,105 @@ namespace net { namespace maildir { -maildirFolder::maildirFolder(const folder::path& path, const shared_ptr & store) - : m_store(store), m_path(path), +maildirFolder::maildirFolder( + const folder::path& path, + const shared_ptr & store +) + : m_store(store), + m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), - m_mode(-1), m_open(false), m_unreadMessageCount(0), m_messageCount(0) -{ + m_mode(-1), + m_open(false), + m_unreadMessageCount(0), + m_messageCount(0) { + store->registerFolder(this); } -maildirFolder::~maildirFolder() -{ - try - { +maildirFolder::~maildirFolder() { + + try { + shared_ptr store = m_store.lock(); - if (store) - { - if (m_open) + if (store) { + + if (m_open) { close(false); + } store->unregisterFolder(this); - } - else if (m_open) - { + + } else if (m_open) { + close(false); } - } - catch (...) - { + + } catch (...) { + // Don't throw in destructor } } -void maildirFolder::onStoreDisconnected() -{ +void maildirFolder::onStoreDisconnected() { + m_store.reset(); } -int maildirFolder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +int maildirFolder::getMode() const { - return (m_mode); + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + return m_mode; } -const folderAttributes maildirFolder::getAttributes() -{ +const folderAttributes maildirFolder::getAttributes() { + folderAttributes attribs; - if (m_path.isEmpty()) + if (m_path.isEmpty()) { attribs.setType(folderAttributes::TYPE_CONTAINS_FOLDERS); - else + } else { attribs.setType(folderAttributes::TYPE_CONTAINS_FOLDERS | folderAttributes::TYPE_CONTAINS_MESSAGES); + } - if (m_store.lock()->getFormat()->folderHasSubfolders(m_path)) + if (m_store.lock()->getFormat()->folderHasSubfolders(m_path)) { attribs.setFlags(folderAttributes::FLAG_HAS_CHILDREN); // contains at least one sub-folder + } return attribs; } -const folder::path::component maildirFolder::getName() const -{ - return (m_name); +const folder::path::component maildirFolder::getName() const { + + return m_name; } -const folder::path maildirFolder::getFullPath() const -{ - return (m_path); +const folder::path maildirFolder::getFullPath() const { + + return m_path; } -void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */) -{ +void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (isOpen()) + } else if (isOpen()) { throw exceptions::illegal_state("Folder is already open"); - else if (!exists()) + } else if (!exists()) { throw exceptions::illegal_state("Folder does not exist"); + } scanFolder(); @@ -144,18 +156,21 @@ void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */) } -void maildirFolder::close(const bool expunge) -{ +void maildirFolder::close(const bool expunge) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - if (!isOpen()) + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (expunge) + if (expunge) { this->expunge(); + } m_open = false; m_mode = -1; @@ -164,11 +179,11 @@ void maildirFolder::close(const bool expunge) } -void maildirFolder::onClose() -{ +void maildirFolder::onClose() { + for (std::vector ::iterator it = m_messages.begin() ; - it != m_messages.end() ; ++it) - { + it != m_messages.end() ; ++it) { + (*it)->onFolderClosed(); } @@ -176,144 +191,147 @@ void maildirFolder::onClose() } -void maildirFolder::registerMessage(maildirMessage* msg) -{ +void maildirFolder::registerMessage(maildirMessage* msg) { + m_messages.push_back(msg); } -void maildirFolder::unregisterMessage(maildirMessage* msg) -{ +void maildirFolder::unregisterMessage(maildirMessage* msg) { + std::vector ::iterator it = std::find(m_messages.begin(), m_messages.end(), msg); - if (it != m_messages.end()) + if (it != m_messages.end()) { m_messages.erase(it); + } } -void maildirFolder::create(const folderAttributes& /* attribs */) -{ +void maildirFolder::create(const folderAttributes& /* attribs */) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (isOpen()) + } else if (isOpen()) { throw exceptions::illegal_state("Folder is open"); - else if (exists()) + } else if (exists()) { throw exceptions::illegal_state("Folder already exists"); - else if (!store->isValidFolderName(m_name)) + } else if (!store->isValidFolderName(m_name)) { throw exceptions::invalid_folder_name(); + } // Create directory on file system - try - { + try { store->getFormat()->createFolder(m_path); - } - catch (exceptions::filesystem_exception& e) - { + } catch (exceptions::filesystem_exception& e) { throw exceptions::command_error("CREATE", "", "File system exception", e); } // Notify folder created shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_CREATED, m_path, m_path); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_CREATED, + m_path, m_path + ); notifyFolder(event); } -void maildirFolder::destroy() -{ +void maildirFolder::destroy() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (isOpen()) + } else if (isOpen()) { throw exceptions::illegal_state("Folder is open"); + } // Delete folder - try - { + try { store->getFormat()->destroyFolder(m_path); - } - catch (std::exception&) - { + } catch (std::exception&) { // Ignore exception: anyway, we can't recover from this... } // Notify folder deleted shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_DELETED, m_path, m_path); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_DELETED, + m_path, m_path + ); notifyFolder(event); } -bool maildirFolder::exists() -{ +bool maildirFolder::exists() { + shared_ptr store = m_store.lock(); return store->getFormat()->folderExists(m_path); } -bool maildirFolder::isOpen() const -{ - return (m_open); +bool maildirFolder::isOpen() const { + + return m_open; } -void maildirFolder::scanFolder() -{ +void maildirFolder::scanFolder() { + shared_ptr store = m_store.lock(); - try - { + try { + m_messageCount = 0; m_unreadMessageCount = 0; shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - utility::file::path newDirPath = store->getFormat()->folderPathToFileSystemPath - (m_path, maildirFormat::NEW_DIRECTORY); + utility::file::path newDirPath = + store->getFormat()->folderPathToFileSystemPath(m_path, maildirFormat::NEW_DIRECTORY); shared_ptr newDir = fsf->create(newDirPath); - utility::file::path curDirPath = store->getFormat()->folderPathToFileSystemPath - (m_path, maildirFormat::CUR_DIRECTORY); + utility::file::path curDirPath = + store->getFormat()->folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); shared_ptr curDir = fsf->create(curDirPath); // New received messages (new/) shared_ptr nit = newDir->getFiles(); std::vector newMessageFilenames; - while (nit->hasMoreElements()) - { + while (nit->hasMoreElements()) { + shared_ptr file = nit->nextElement(); - if (maildirUtils::isMessageFile(*file)) + if (maildirUtils::isMessageFile(*file)) { newMessageFilenames.push_back(file->getFullPath().getLastComponent()); + } } // Current messages (cur/) shared_ptr cit = curDir->getFiles(); std::vector curMessageFilenames; - while (cit->hasMoreElements()) - { + while (cit->hasMoreElements()) { + shared_ptr file = cit->nextElement(); - if (maildirUtils::isMessageFile(*file)) + if (maildirUtils::isMessageFile(*file)) { curMessageFilenames.push_back(file->getFullPath().getLastComponent()); + } } // Update/delete existing messages (found in previous scan) - for (size_t i = 0 ; i < m_messageInfos.size() ; ++i) - { + for (size_t i = 0 ; i < m_messageInfos.size() ; ++i) { + messageInfos& msgInfos = m_messageInfos[i]; // NOTE: the flags may have changed (eg. moving from 'new' to 'cur' @@ -321,21 +339,24 @@ void maildirFolder::scanFolder() // "maildirUtils::messageIdComparator" to compare only the 'unique' // portion of the filename... - if (msgInfos.type == messageInfos::TYPE_CUR) - { + if (msgInfos.type == messageInfos::TYPE_CUR) { + const std::vector ::iterator pos = - std::find_if(curMessageFilenames.begin(), curMessageFilenames.end(), - maildirUtils::messageIdComparator(msgInfos.path)); + std::find_if( + curMessageFilenames.begin(), + curMessageFilenames.end(), + maildirUtils::messageIdComparator(msgInfos.path) + ); // If we cannot find this message in the 'cur' directory, // it means it has been deleted (and expunged). - if (pos == curMessageFilenames.end()) - { + if (pos == curMessageFilenames.end()) { + msgInfos.type = messageInfos::TYPE_DELETED; - } + // Otherwise, update its information. - else - { + } else { + msgInfos.path = *pos; curMessageFilenames.erase(pos); } @@ -349,8 +370,8 @@ void maildirFolder::scanFolder() // from the 'new' directory to the 'cur' directory, and append them // to our message list. for (std::vector ::const_iterator - it = newMessageFilenames.begin() ; it != newMessageFilenames.end() ; ++it) - { + it = newMessageFilenames.begin() ; it != newMessageFilenames.end() ; ++it) { + const utility::file::path::component newFilename = maildirUtils::buildFilename(maildirUtils::extractId(*it), 0); @@ -362,10 +383,11 @@ void maildirFolder::scanFolder() messageInfos msgInfos; msgInfos.path = newFilename; - if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED) + if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED) { msgInfos.type = messageInfos::TYPE_DELETED; - else + } else { msgInfos.type = messageInfos::TYPE_CUR; + } m_messageInfos.push_back(msgInfos); } @@ -373,16 +395,17 @@ void maildirFolder::scanFolder() // Add new messages from 'cur': the files have already been moved // from 'new' to 'cur'. Just append them to our message list. for (std::vector ::const_iterator - it = curMessageFilenames.begin() ; it != curMessageFilenames.end() ; ++it) - { + it = curMessageFilenames.begin() ; it != curMessageFilenames.end() ; ++it) { + // Append to message list messageInfos msgInfos; msgInfos.path = *it; - if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED) + if (maildirUtils::extractFlags(msgInfos.path) & message::FLAG_DELETED) { msgInfos.type = messageInfos::TYPE_DELETED; - else + } else { msgInfos.type = messageInfos::TYPE_CUR; + } m_messageInfos.push_back(msgInfos); } @@ -391,140 +414,145 @@ void maildirFolder::scanFolder() size_t unreadMessageCount = 0; for (std::vector ::const_iterator - it = m_messageInfos.begin() ; it != m_messageInfos.end() ; ++it) - { - if ((maildirUtils::extractFlags((*it).path) & message::FLAG_SEEN) == 0) + it = m_messageInfos.begin() ; it != m_messageInfos.end() ; ++it) { + + if ((maildirUtils::extractFlags((*it).path) & message::FLAG_SEEN) == 0) { ++unreadMessageCount; + } } m_unreadMessageCount = unreadMessageCount; m_messageCount = static_cast (m_messageInfos.size()); - } - catch (exceptions::filesystem_exception&) - { + + } catch (exceptions::filesystem_exception&) { + // Should not happen... } } -shared_ptr maildirFolder::getMessage(const size_t num) -{ - if (!isOpen()) +shared_ptr maildirFolder::getMessage(const size_t num) { + + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (num < 1 || num > m_messageCount) + if (num < 1 || num > m_messageCount) { throw exceptions::message_not_found(); + } - return make_shared - (dynamicCast (shared_from_this()), num); + return make_shared (dynamicCast (shared_from_this()), num); } -std::vector > maildirFolder::getMessages(const messageSet& msgs) -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +std::vector > maildirFolder::getMessages(const messageSet& msgs) { + + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + if (msgs.isNumberSet()) { - if (msgs.isNumberSet()) - { const std::vector numbers = maildirUtils::messageSetToNumberList(msgs, m_messageCount); std::vector > messages; shared_ptr thisFolder = dynamicCast (shared_from_this()); - for (std::vector ::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it) - { - if (*it < 1|| *it > m_messageCount) + for (std::vector ::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it) { + + if (*it < 1|| *it > m_messageCount) { throw exceptions::message_not_found(); + } messages.push_back(make_shared (thisFolder, *it)); } return messages; - } - else - { + + } else { + throw exceptions::operation_not_supported(); } } -size_t maildirFolder::getMessageCount() -{ - return (m_messageCount); +size_t maildirFolder::getMessageCount() { + + return m_messageCount; } -shared_ptr maildirFolder::getFolder(const folder::path::component& name) -{ +shared_ptr maildirFolder::getFolder(const folder::path::component& name) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } return shared_ptr (new maildirFolder(m_path / name, store)); } -std::vector > maildirFolder::getFolders(const bool recursive) -{ +std::vector > maildirFolder::getFolders(const bool recursive) { + shared_ptr store = m_store.lock(); - if (!isOpen() && !store) + if (!isOpen() && !store) { throw exceptions::illegal_state("Store disconnected"); + } std::vector > list; listFolders(list, recursive); - return (list); + return list; } -void maildirFolder::listFolders(std::vector >& list, const bool recursive) -{ +void maildirFolder::listFolders(std::vector >& list, const bool recursive) { + shared_ptr store = m_store.lock(); - try - { + try { + std::vector pathList = store->getFormat()->listFolders(m_path, recursive); list.reserve(pathList.size()); - for (std::vector ::size_type i = 0, n = pathList.size() ; i < n ; ++i) - { - shared_ptr subFolder = - shared_ptr (new maildirFolder(pathList[i], store)); + for (std::vector ::size_type i = 0, n = pathList.size() ; i < n ; ++i) { + + shared_ptr subFolder( + new maildirFolder(pathList[i], store) + ); list.push_back(subFolder); } - } - catch (exceptions::filesystem_exception& e) - { + + } catch (exceptions::filesystem_exception& e) { + throw exceptions::command_error("LIST", "", "", e); } } -void maildirFolder::rename(const folder::path& newPath) -{ +void maildirFolder::rename(const folder::path& newPath) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (m_path.isEmpty() || newPath.isEmpty()) + } else if (m_path.isEmpty() || newPath.isEmpty()) { throw exceptions::illegal_operation("Cannot rename root folder"); - else if (!store->isValidFolderName(newPath.getLastComponent())) + } else if (!store->isValidFolderName(newPath.getLastComponent())) { throw exceptions::invalid_folder_name(); + } // Rename the directory on the file system - try - { + try { store->getFormat()->renameFolder(m_path, newPath); - } - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { throw exceptions::command_error("RENAME", "", "", e); } @@ -535,38 +563,44 @@ void maildirFolder::rename(const folder::path& newPath) m_name = newPath.getLastComponent(); shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::folderEvent::TYPE_RENAMED, oldPath, newPath); + make_shared ( + dynamicCast (shared_from_this()), + events::folderEvent::TYPE_RENAMED, + oldPath, newPath + ); notifyFolder(event); // Notify folders with the same path for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == oldPath) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == oldPath) { + (*it)->m_path = newPath; (*it)->m_name = newPath.getLastComponent(); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::folderEvent::TYPE_RENAMED, oldPath, newPath); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::folderEvent::TYPE_RENAMED, + oldPath, newPath + ); (*it)->notifyFolder(event); - } - else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) - { + + } else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) { + folder::path oldPath((*it)->m_path); (*it)->m_path.renameParent(oldPath, newPath); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::folderEvent::TYPE_RENAMED, + oldPath, (*it)->m_path + ); (*it)->notifyFolder(event); } @@ -574,27 +608,31 @@ void maildirFolder::rename(const folder::path& newPath) } -void maildirFolder::deleteMessages(const messageSet& msgs) -{ +void maildirFolder::deleteMessages(const messageSet& msgs) { + // Mark messages as deleted setMessageFlags(msgs, message::FLAG_DELETED, message::FLAG_MODE_ADD); } -void maildirFolder::setMessageFlags - (const messageSet& msgs, const int flags, const int mode) -{ +void maildirFolder::setMessageFlags( + const messageSet& msgs, + const int flags, + const int mode +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } + + if (msgs.isNumberSet()) { - if (msgs.isNumberSet()) - { const std::vector nums = maildirUtils::messageSetToNumberList(msgs, m_messageCount); // Change message flags @@ -604,113 +642,118 @@ void maildirFolder::setMessageFlags folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); for (std::vector ::const_iterator it = - nums.begin() ; it != nums.end() ; ++it) - { + nums.begin() ; it != nums.end() ; ++it) { + const size_t num = *it - 1; - try - { + try { + const utility::file::path::component path = m_messageInfos[num].path; shared_ptr file = fsf->create(curDirPath / path); int newFlags = maildirUtils::extractFlags(path); - switch (mode) - { - case message::FLAG_MODE_ADD: newFlags |= flags; break; - case message::FLAG_MODE_REMOVE: newFlags &= ~flags; break; - default: - case message::FLAG_MODE_SET: newFlags = flags; break; + switch (mode) { + case message::FLAG_MODE_ADD: newFlags |= flags; break; + case message::FLAG_MODE_REMOVE: newFlags &= ~flags; break; + default: + case message::FLAG_MODE_SET: newFlags = flags; break; } - const utility::file::path::component newPath = maildirUtils::buildFilename - (maildirUtils::extractId(path), newFlags); + const utility::file::path::component newPath = + maildirUtils::buildFilename(maildirUtils::extractId(path), newFlags); file->rename(curDirPath / newPath); - if (flags & message::FLAG_DELETED) + if (flags & message::FLAG_DELETED) { m_messageInfos[num].type = messageInfos::TYPE_DELETED; - else + } else { m_messageInfos[num].type = messageInfos::TYPE_CUR; + } m_messageInfos[num].path = newPath; - } - catch (exceptions::filesystem_exception& e) - { + + } catch (exceptions::filesystem_exception& e) { + // Ignore (not important) } } // Update local flags - switch (mode) - { - case message::FLAG_MODE_ADD: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && - (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) - { - (*it)->m_flags |= flags; - } - } + switch (mode) { - break; - } - case message::FLAG_MODE_REMOVE: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && - (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) - { - (*it)->m_flags &= ~flags; - } - } + case message::FLAG_MODE_ADD: { - break; - } - default: - case message::FLAG_MODE_SET: - { - for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && - (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) - { - (*it)->m_flags = flags; - } - } + for (std::vector ::iterator it = + m_messages.begin() ; it != m_messages.end() ; ++it) { - break; - } + if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && + (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) { + + (*it)->m_flags |= flags; + } + } + + break; + } + case message::FLAG_MODE_REMOVE: { + + for (std::vector ::iterator it = + m_messages.begin() ; it != m_messages.end() ; ++it) { + + if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && + (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) { + + (*it)->m_flags &= ~flags; + } + } + + break; + } + default: + case message::FLAG_MODE_SET: { + + for (std::vector ::iterator it = + m_messages.begin() ; it != m_messages.end() ; ++it) { + + if (std::binary_search(nums.begin(), nums.end(), (*it)->getNumber()) && + (*it)->m_flags != maildirMessage::FLAG_UNDEFINED) { + + (*it)->m_flags = flags; + } + } + + break; + } } // Notify message flags changed shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageChangedEvent::TYPE_FLAGS, nums); + make_shared ( + dynamicCast (shared_from_this()), + events::messageChangedEvent::TYPE_FLAGS, + nums + ); notifyMessageChanged(event); // TODO: notify other folders with the same path - } - else - { + + } else { + throw exceptions::operation_not_supported(); } } -messageSet maildirFolder::addMessage - (const shared_ptr & msg, const int flags, - vmime::datetime* date, utility::progressListener* progress) -{ +messageSet maildirFolder::addMessage( + const shared_ptr & msg, + const int flags, + vmime::datetime* date, + utility::progressListener* progress +) { + std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); @@ -723,50 +766,50 @@ messageSet maildirFolder::addMessage } -messageSet maildirFolder::addMessage - (utility::inputStream& is, const size_t size, - const int flags, vmime::datetime* /* date */, utility::progressListener* progress) -{ +messageSet maildirFolder::addMessage( + utility::inputStream& is, + const size_t size, + const int flags, + vmime::datetime* /* date */, + utility::progressListener* progress +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path tmpDirPath = store->getFormat()-> folderPathToFileSystemPath(m_path,maildirFormat::TMP_DIRECTORY); utility::file::path dstDirPath = store->getFormat()-> - folderPathToFileSystemPath(m_path, + folderPathToFileSystemPath( + m_path, flags == message::FLAG_RECENT ? maildirFormat::NEW_DIRECTORY : - maildirFormat::CUR_DIRECTORY); + maildirFormat::CUR_DIRECTORY + ); const utility::file::path::component filename = - maildirUtils::buildFilename(maildirUtils::generateId(), - ((flags == -1) ? 0 : flags)); + maildirUtils::buildFilename(maildirUtils::generateId(), ((flags == -1) ? 0 : flags)); - try - { + try { shared_ptr tmpDir = fsf->create(tmpDirPath); tmpDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { + } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } - try - { + try { shared_ptr curDir = fsf->create(dstDirPath); curDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { + } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } @@ -781,26 +824,29 @@ messageSet maildirFolder::addMessage m_messageInfos.push_back(msgInfos); m_messageCount++; - if ((flags == -1) || !(flags & message::FLAG_SEEN)) + if ((flags == -1) || !(flags & message::FLAG_SEEN)) { m_unreadMessageCount++; + } // Notification std::vector nums; nums.push_back(m_messageCount); shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); notifyMessageCount(event); // Notify folders with the same path for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == m_path) { + (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; @@ -808,9 +854,11 @@ messageSet maildirFolder::addMessage std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); (*it)->notifyMessageCount(event); } @@ -820,22 +868,25 @@ messageSet maildirFolder::addMessage } -void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, +void maildirFolder::copyMessageImpl( + const utility::file::path& tmpDirPath, const utility::file::path& dstDirPath, const utility::file::path::component& filename, utility::inputStream& is, const size_t size, - utility::progressListener* progress) -{ + utility::progressListener* progress +) { + shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); shared_ptr file = fsf->create(tmpDirPath / filename); - if (progress) + if (progress) { progress->start(size); + } // First, write the message into 'tmp'... - try - { + try { + file->createFile(); shared_ptr fw = file->getFileWriter(); @@ -844,35 +895,33 @@ void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, byte_t buffer[65536]; size_t total = 0; - while (!is.eof()) - { + while (!is.eof()) { + const size_t read = is.read(buffer, sizeof(buffer)); - if (read != 0) - { + if (read != 0) { os->write(buffer, read); total += read; } - if (progress) + if (progress) { progress->progress(total, size); + } } os->flush(); - } - catch (exception& e) - { - if (progress) + + } catch (exception& e) { + + if (progress) { progress->stop(size); + } // Delete temporary file - try - { + try { shared_ptr file = fsf->create(tmpDirPath / filename); file->remove(); - } - catch (exceptions::filesystem_exception&) - { + } catch (exceptions::filesystem_exception&) { // Ignore } @@ -880,48 +929,51 @@ void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, } // ...then, move it to 'cur' - try - { + try { + file->rename(dstDirPath / filename); - } - catch (exception& e) - { - if (progress) + + } catch (exception& e) { + + if (progress) { progress->stop(size); + } // Delete temporary file - try - { + try { + file->remove(); shared_ptr file = fsf->create(dstDirPath / filename); file->remove(); - } - catch (exceptions::filesystem_exception&) - { + + } catch (exceptions::filesystem_exception&) { + // Ignore } throw exceptions::command_error("ADD", "", "", e); } - if (progress) + if (progress) { progress->stop(size); + } } -messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSet& msgs) -{ +messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSet& msgs) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); - utility::file::path curDirPath = store->getFormat()->folderPathToFileSystemPath - (m_path, maildirFormat::CUR_DIRECTORY); + utility::file::path curDirPath = + store->getFormat()->folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); utility::file::path destCurDirPath = store->getFormat()-> folderPathToFileSystemPath(dest, maildirFormat::CUR_DIRECTORY); @@ -929,34 +981,34 @@ messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSe folderPathToFileSystemPath(dest, maildirFormat::TMP_DIRECTORY); // Create destination directories - try - { + try { + shared_ptr destTmpDir = fsf->create(destTmpDirPath); destTmpDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { + + } catch (exceptions::filesystem_exception&) { + // Don't throw now, it will fail later... } - try - { + try { + shared_ptr destCurDir = fsf->create(destCurDirPath); destCurDir->createDirectory(true); - } - catch (exceptions::filesystem_exception&) - { + + } catch (exceptions::filesystem_exception&) { + // Don't throw now, it will fail later... } // Copy messages const std::vector nums = maildirUtils::messageSetToNumberList(msgs, m_messageCount); - try - { + try { + for (std::vector ::const_iterator it = - nums.begin() ; it != nums.end() ; ++it) - { + nums.begin() ; it != nums.end() ; ++it) { + const size_t num = *it; const messageInfos& msg = m_messageInfos[num - 1]; const int flags = maildirUtils::extractFlags(msg.path); @@ -971,9 +1023,9 @@ messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSe copyMessageImpl(destTmpDirPath, destCurDirPath, filename, *is, file->getLength(), NULL); } - } - catch (exception& e) - { + + } catch (exception& e) { + notifyMessagesCopied(dest); throw exceptions::command_error("COPY", "", "", e); } @@ -984,15 +1036,15 @@ messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSe } -void maildirFolder::notifyMessagesCopied(const folder::path& dest) -{ +void maildirFolder::notifyMessagesCopied(const folder::path& dest) { + shared_ptr store = m_store.lock(); for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == dest) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == dest) { + // We only need to update the first folder we found as calling // status() will notify all the folders with the same path. size_t count, unseen; @@ -1004,8 +1056,8 @@ void maildirFolder::notifyMessagesCopied(const folder::path& dest) } -void maildirFolder::status(size_t& count, size_t& unseen) -{ +void maildirFolder::status(size_t& count, size_t& unseen) { + count = 0; unseen = 0; @@ -1018,8 +1070,8 @@ void maildirFolder::status(size_t& count, size_t& unseen) } -shared_ptr maildirFolder::getStatus() -{ +shared_ptr maildirFolder::getStatus() { + shared_ptr store = m_store.lock(); const size_t oldCount = m_messageCount; @@ -1032,27 +1084,30 @@ shared_ptr maildirFolder::getStatus() status->setUnseenCount(m_unreadMessageCount); // Notify message count changed (new messages) - if (m_messageCount > oldCount) - { + if (m_messageCount > oldCount) { + std::vector nums; nums.reserve(m_messageCount - oldCount); - for (size_t i = oldCount + 1, j = 0 ; i <= m_messageCount ; ++i, ++j) + for (size_t i = oldCount + 1, j = 0 ; i <= m_messageCount ; ++i, ++j) { nums[j] = i; + } shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); notifyMessageCount(event); // Notify folders with the same path for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == m_path) { + (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; @@ -1060,9 +1115,11 @@ shared_ptr maildirFolder::getStatus() std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); (*it)->notifyMessageCount(event); } @@ -1073,16 +1130,17 @@ shared_ptr maildirFolder::getStatus() } -void maildirFolder::expunge() -{ +void maildirFolder::expunge() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (m_mode == MODE_READ_ONLY) + } else if (m_mode == MODE_READ_ONLY) { throw exceptions::illegal_state("Folder is read-only"); + } shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); @@ -1092,43 +1150,43 @@ void maildirFolder::expunge() std::vector nums; size_t unreadCount = 0; - for (size_t num = 1 ; num <= m_messageCount ; ++num) - { + for (size_t num = 1 ; num <= m_messageCount ; ++num) { + messageInfos& infos = m_messageInfos[num - 1]; - if (infos.type == messageInfos::TYPE_DELETED) - { + if (infos.type == messageInfos::TYPE_DELETED) { + nums.push_back(num); for (std::vector ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { - if ((*it)->m_num == num) + m_messages.begin() ; it != m_messages.end() ; ++it) { + + if ((*it)->m_num == num) { (*it)->m_expunged = true; - else if ((*it)->m_num > num) + } else if ((*it)->m_num > num) { (*it)->m_num--; + } } - if (maildirUtils::extractFlags(infos.path) & message::FLAG_SEEN) + if (maildirUtils::extractFlags(infos.path) & message::FLAG_SEEN) { ++unreadCount; + } // Delete file from file system - try - { + try { shared_ptr file = fsf->create(curDirPath / infos.path); file->remove(); - } - catch (exceptions::filesystem_exception& e) - { + } catch (exceptions::filesystem_exception& e) { // Ignore (not important) } } } - if (!nums.empty()) - { - for (std::vector ::size_type i = nums.size() ; i != 0 ; --i) + if (!nums.empty()) { + + for (std::vector ::size_type i = nums.size() ; i != 0 ; --i) { m_messageInfos.erase(m_messageInfos.begin() + (i - 1)); + } } m_messageCount -= static_cast (nums.size()); @@ -1136,18 +1194,20 @@ void maildirFolder::expunge() // Notify message expunged shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_REMOVED, nums); + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_REMOVED, + nums + ); notifyMessageCount(event); // Notify folders with the same path for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == m_path) { + (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; @@ -1155,9 +1215,11 @@ void maildirFolder::expunge() std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::messageCountEvent::TYPE_REMOVED, nums); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::messageCountEvent::TYPE_REMOVED, + nums + ); (*it)->notifyMessageCount(event); } @@ -1165,81 +1227,99 @@ void maildirFolder::expunge() } -shared_ptr maildirFolder::getParent() -{ - if (m_path.isEmpty()) +shared_ptr maildirFolder::getParent() { + + if (m_path.isEmpty()) { return null; - else + } else { return shared_ptr (new maildirFolder(m_path.getParent(), m_store.lock())); + } } -shared_ptr maildirFolder::getStore() const -{ +shared_ptr maildirFolder::getStore() const { + return m_store.lock(); } -shared_ptr maildirFolder::getStore() -{ +shared_ptr maildirFolder::getStore() { + return m_store.lock(); } -void maildirFolder::fetchMessages(std::vector >& msg, - const fetchAttributes& options, utility::progressListener* progress) -{ +void maildirFolder::fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (msg.empty()) + if (msg.empty()) { return; + } const size_t total = msg.size(); size_t current = 0; - if (progress) + if (progress) { progress->start(total); + } shared_ptr thisFolder = dynamicCast (shared_from_this()); for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { + it != msg.end() ; ++it) { + dynamicCast (*it)->fetch(thisFolder, options); - if (progress) + if (progress) { progress->progress(++current, total); + } } - if (progress) + if (progress) { progress->stop(total); + } } -void maildirFolder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) -{ +void maildirFolder::fetchMessage( + const shared_ptr & msg, + const fetchAttributes& options +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - dynamicCast (msg)->fetch - (dynamicCast (shared_from_this()), options); + dynamicCast (msg)->fetch( + dynamicCast (shared_from_this()), + options + ); } -std::vector > maildirFolder::getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs) -{ - if (msgs.isEmpty()) +std::vector > maildirFolder::getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs +) { + + if (msgs.isEmpty()) { return std::vector >(); + } std::vector > messages = getMessages(msgs); fetchMessages(messages, attribs); @@ -1248,26 +1328,30 @@ std::vector > maildirFolder::getAndFetchMessages } -int maildirFolder::getFetchCapabilities() const -{ - return fetchAttributes::ENVELOPE | fetchAttributes::STRUCTURE | - fetchAttributes::CONTENT_INFO | fetchAttributes::FLAGS | - fetchAttributes::SIZE | fetchAttributes::FULL_HEADER | - fetchAttributes::UID | fetchAttributes::IMPORTANCE; +int maildirFolder::getFetchCapabilities() const { + + return fetchAttributes::ENVELOPE | + fetchAttributes::STRUCTURE | + fetchAttributes::CONTENT_INFO | + fetchAttributes::FLAGS | + fetchAttributes::SIZE | + fetchAttributes::FULL_HEADER | + fetchAttributes::UID | + fetchAttributes::IMPORTANCE; } -const utility::file::path maildirFolder::getMessageFSPath(const size_t number) const -{ +const utility::file::path maildirFolder::getMessageFSPath(const size_t number) const { + utility::file::path curDirPath = m_store.lock()->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); - return (curDirPath / m_messageInfos[number - 1].path); + return curDirPath / m_messageInfos[number - 1].path; } -std::vector maildirFolder::getMessageNumbersStartingOnUID(const message::uid& /* uid */) -{ +std::vector maildirFolder::getMessageNumbersStartingOnUID(const message::uid& /* uid */) { + throw exceptions::operation_not_supported(); } diff --git a/src/vmime/net/maildir/maildirFolder.hpp b/src/vmime/net/maildir/maildirFolder.hpp index ff0cff61..24f2bf86 100644 --- a/src/vmime/net/maildir/maildirFolder.hpp +++ b/src/vmime/net/maildir/maildirFolder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,9 +52,8 @@ class maildirMessage; /** maildir folder implementation. */ +class VMIME_EXPORT maildirFolder : public folder { -class VMIME_EXPORT maildirFolder : public folder -{ private: friend class maildirStore; @@ -97,10 +96,26 @@ public: void deleteMessages(const messageSet& msgs); - void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + void setMessageFlags( + const messageSet& msgs, + const int flags, + const int mode = message::FLAG_MODE_SET + ); - messageSet addMessage(const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); - messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + messageSet addMessage( + const shared_ptr & msg, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); + + messageSet addMessage( + utility::inputStream& is, + const size_t size, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); messageSet copyMessages(const folder::path& dest, const messageSet& msgs); @@ -115,11 +130,18 @@ public: shared_ptr getStore(); - void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress = NULL + ); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); - std::vector > getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs); + std::vector > getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs + ); int getFetchCapabilities() const; @@ -161,10 +183,9 @@ private: size_t m_messageCount; // Store information about scanned messages - struct messageInfos - { - enum Type - { + struct messageInfos { + + enum Type { TYPE_CUR, TYPE_DELETED }; diff --git a/src/vmime/net/maildir/maildirFolderStatus.cpp b/src/vmime/net/maildir/maildirFolderStatus.cpp index 9817c1ca..7438d8cf 100644 --- a/src/vmime/net/maildir/maildirFolderStatus.cpp +++ b/src/vmime/net/maildir/maildirFolderStatus.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,45 +37,45 @@ namespace maildir { maildirFolderStatus::maildirFolderStatus() : m_count(0), - m_unseen(0) -{ + m_unseen(0) { + } maildirFolderStatus::maildirFolderStatus(const maildirFolderStatus& other) : folderStatus(), m_count(other.m_count), - m_unseen(other.m_unseen) -{ + m_unseen(other.m_unseen) { + } -size_t maildirFolderStatus::getMessageCount() const -{ +size_t maildirFolderStatus::getMessageCount() const { + return m_count; } -size_t maildirFolderStatus::getUnseenCount() const -{ +size_t maildirFolderStatus::getUnseenCount() const { + return m_unseen; } -void maildirFolderStatus::setMessageCount(const size_t count) -{ +void maildirFolderStatus::setMessageCount(const size_t count) { + m_count = count; } -void maildirFolderStatus::setUnseenCount(const size_t unseen) -{ +void maildirFolderStatus::setUnseenCount(const size_t unseen) { + m_unseen = unseen; } -shared_ptr maildirFolderStatus::clone() const -{ +shared_ptr maildirFolderStatus::clone() const { + return make_shared (*this); } diff --git a/src/vmime/net/maildir/maildirFolderStatus.hpp b/src/vmime/net/maildir/maildirFolderStatus.hpp index 0921f01e..3b69375a 100644 --- a/src/vmime/net/maildir/maildirFolderStatus.hpp +++ b/src/vmime/net/maildir/maildirFolderStatus.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,9 +41,8 @@ namespace maildir { /** Holds the status of a Maildir folder. */ +class VMIME_EXPORT maildirFolderStatus : public folderStatus { -class VMIME_EXPORT maildirFolderStatus : public folderStatus -{ public: maildirFolderStatus(); diff --git a/src/vmime/net/maildir/maildirFormat.cpp b/src/vmime/net/maildir/maildirFormat.cpp index 7f2cb5f1..914c0786 100644 --- a/src/vmime/net/maildir/maildirFormat.cpp +++ b/src/vmime/net/maildir/maildirFormat.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,13 +51,13 @@ const utility::file::path::component maildirFormat::NEW_DIR("new", vmime::charse // maildirFormat::context::context(const shared_ptr & store) - : m_store(store) -{ + : m_store(store) { + } -shared_ptr maildirFormat::context::getStore() -{ +shared_ptr maildirFormat::context::getStore() { + return m_store.lock(); } @@ -67,27 +67,28 @@ shared_ptr maildirFormat::context::getStore() // maildirFormat::maildirFormat(const shared_ptr & ctx) - : m_context(ctx) -{ + : m_context(ctx) { + } -shared_ptr maildirFormat::getContext() const -{ +shared_ptr maildirFormat::getContext() const { + return m_context; } // static -shared_ptr maildirFormat::detect(const shared_ptr & store) -{ +shared_ptr maildirFormat::detect(const shared_ptr & store) { + shared_ptr ctx = make_shared (store); // Try Courier format shared_ptr fmt = make_shared (ctx); - if (fmt->supports()) + if (fmt->supports()) { return fmt; + } // Default is KMail format return make_shared (ctx); diff --git a/src/vmime/net/maildir/maildirFormat.hpp b/src/vmime/net/maildir/maildirFormat.hpp index 733303bd..9b9e0636 100644 --- a/src/vmime/net/maildir/maildirFormat.hpp +++ b/src/vmime/net/maildir/maildirFormat.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,14 +45,14 @@ namespace maildir { class maildirStore; -/** Interface for an object capable of reading a specific Maildir format. */ +/** Interface for an object capable of reading a specific Maildir format. + */ +class VMIME_EXPORT maildirFormat : public object { -class VMIME_EXPORT maildirFormat : public object -{ public: - class context : public object - { + class context : public object { + public: context(const shared_ptr & store); @@ -66,8 +66,7 @@ public: /** Physical directory types. */ - enum DirectoryType - { + enum DirectoryType { ROOT_DIRECTORY, /**< Root directory. */ NEW_DIRECTORY, /**< Directory containing unread messages. */ CUR_DIRECTORY, /**< Directory containing messages that have been seen. */ @@ -125,8 +124,10 @@ public: * @param type type of directory to return * @return corresponding directory on the file system */ - virtual const utility::file::path folderPathToFileSystemPath - (const folder::path& path, const DirectoryType type) const = 0; + virtual const utility::file::path folderPathToFileSystemPath( + const folder::path& path, + const DirectoryType type + ) const = 0; /** List subfolders in the specified folder. * @@ -135,8 +136,10 @@ public: * returned; if set to false, only direct children are returned. * @return list of subfolders */ - virtual const std::vector listFolders - (const folder::path& root, const bool recursive) const = 0; + virtual const std::vector listFolders( + const folder::path& root, + const bool recursive + ) const = 0; /** Try to detect the format of the specified Maildir store. diff --git a/src/vmime/net/maildir/maildirMessage.cpp b/src/vmime/net/maildir/maildirMessage.cpp index ea3d05a6..ae99c597 100644 --- a/src/vmime/net/maildir/maildirMessage.cpp +++ b/src/vmime/net/maildir/maildirMessage.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,132 +49,160 @@ namespace maildir { maildirMessage::maildirMessage(const shared_ptr & folder, const size_t num) - : m_folder(folder), m_num(num), m_size(-1), m_flags(FLAG_UNDEFINED), - m_expunged(false), m_structure(null) -{ + : m_folder(folder), + m_num(num), + m_size(-1), + m_flags(FLAG_UNDEFINED), + m_expunged(false), + m_structure(null) { + folder->registerMessage(this); } -maildirMessage::~maildirMessage() -{ - try - { +maildirMessage::~maildirMessage() { + + try { + shared_ptr folder = m_folder.lock(); - if (folder) + if (folder) { folder->unregisterMessage(this); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void maildirMessage::onFolderClosed() -{ +void maildirMessage::onFolderClosed() { + m_folder.reset(); } -size_t maildirMessage::getNumber() const -{ - return (m_num); +size_t maildirMessage::getNumber() const { + + return m_num; } -const message::uid maildirMessage::getUID() const -{ - return (m_uid); +const message::uid maildirMessage::getUID() const { + + return m_uid; } -size_t maildirMessage::getSize() const -{ - if (m_size == static_cast (-1)) +size_t maildirMessage::getSize() const { + + if (m_size == static_cast (-1)) { throw exceptions::unfetched_object(); + } - return (m_size); + return m_size; } -bool maildirMessage::isExpunged() const -{ - return (m_expunged); +bool maildirMessage::isExpunged() const { + + return m_expunged; } -shared_ptr maildirMessage::getStructure() const -{ - if (m_structure == NULL) +shared_ptr maildirMessage::getStructure() const { + + if (!m_structure) { throw exceptions::unfetched_object(); + } return m_structure; } -shared_ptr maildirMessage::getStructure() -{ - if (m_structure == NULL) +shared_ptr maildirMessage::getStructure() { + + if (!m_structure) { throw exceptions::unfetched_object(); + } return m_structure; } -shared_ptr maildirMessage::getHeader() const -{ - if (m_header == NULL) - throw exceptions::unfetched_object(); +shared_ptr maildirMessage::getHeader() const { - return (m_header); + if (!m_header) { + throw exceptions::unfetched_object(); + } + + return m_header; } -int maildirMessage::getFlags() const -{ - if (m_flags == FLAG_UNDEFINED) - throw exceptions::unfetched_object(); +int maildirMessage::getFlags() const { - return (m_flags); + if (m_flags == FLAG_UNDEFINED) { + throw exceptions::unfetched_object(); + } + + return m_flags; } -void maildirMessage::setFlags(const int flags, const int mode) -{ +void maildirMessage::setFlags(const int flags, const int mode) { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::folder_not_found(); + } folder->setMessageFlags(messageSet::byNumber(m_num), flags, mode); } -void maildirMessage::extract(utility::outputStream& os, - utility::progressListener* progress, const size_t start, - const size_t length, const bool peek) const -{ +void maildirMessage::extract( + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const bool peek +) const { + extractImpl(os, progress, 0, m_size, start, length, peek); } -void maildirMessage::extractPart(const shared_ptr & p, utility::outputStream& os, - utility::progressListener* progress, const size_t start, - const size_t length, const bool peek) const -{ +void maildirMessage::extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const bool peek +) const { + shared_ptr mp = dynamicCast (p); - extractImpl(os, progress, mp->getBodyParsedOffset(), mp->getBodyParsedLength(), - start, length, peek); + extractImpl( + os, progress, mp->getBodyParsedOffset(), mp->getBodyParsedLength(), + start, length, peek + ); } -void maildirMessage::extractImpl(utility::outputStream& os, utility::progressListener* progress, - const size_t start, const size_t length, const size_t partialStart, const size_t partialLength, - const bool /* peek */) const -{ +void maildirMessage::extractImpl( + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const size_t partialStart, + const size_t partialLength, + const bool /* peek */ +) const { + shared_ptr folder = m_folder.lock(); shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); @@ -188,17 +216,21 @@ void maildirMessage::extractImpl(utility::outputStream& os, utility::progressLis is->skip(start + partialStart); byte_t buffer[8192]; - size_t remaining = (partialLength == static_cast (-1) - ? length : std::min(partialLength, length)); + size_t remaining = + (partialLength == static_cast (-1) + ? length + : std::min(partialLength, length) + ); const size_t total = remaining; size_t current = 0; - if (progress) + if (progress) { progress->start(total); + } + + while (!is->eof() && remaining > 0) { - while (!is->eof() && remaining > 0) - { const size_t read = is->read(buffer, std::min(remaining, sizeof(buffer))); remaining -= read; @@ -206,19 +238,21 @@ void maildirMessage::extractImpl(utility::outputStream& os, utility::progressLis os.write(buffer, read); - if (progress) + if (progress) { progress->progress(current, total); + } } - if (progress) + if (progress) { progress->stop(total); + } // TODO: mark as read unless 'peek' is set } -void maildirMessage::fetchPartHeader(const shared_ptr & p) -{ +void maildirMessage::fetchPartHeader(const shared_ptr & p) { + shared_ptr folder = m_folder.lock(); shared_ptr mp = dynamicCast (p); @@ -239,8 +273,8 @@ void maildirMessage::fetchPartHeader(const shared_ptr & p) string contents; contents.reserve(remaining); - while (!is->eof() && remaining > 0) - { + while (!is->eof() && remaining > 0) { + const size_t read = is->read(buffer, std::min(remaining, sizeof(buffer))); remaining -= read; @@ -252,71 +286,71 @@ void maildirMessage::fetchPartHeader(const shared_ptr & p) } -void maildirMessage::fetch(const shared_ptr & msgFolder, const fetchAttributes& options) -{ +void maildirMessage::fetch(const shared_ptr & msgFolder, const fetchAttributes& options) { + shared_ptr folder = m_folder.lock(); - if (folder != msgFolder) + if (folder != msgFolder) { throw exceptions::folder_not_found(); + } shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); const utility::file::path path = folder->getMessageFSPath(m_num); shared_ptr file = fsf->create(path); - if (options.has(fetchAttributes::FLAGS)) + if (options.has(fetchAttributes::FLAGS)) { m_flags = maildirUtils::extractFlags(path.getLastComponent()); + } - if (options.has(fetchAttributes::SIZE)) + if (options.has(fetchAttributes::SIZE)) { m_size = file->getLength(); + } - if (options.has(fetchAttributes::UID)) + if (options.has(fetchAttributes::UID)) { m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer(); + } if (options.has(fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | fetchAttributes::FULL_HEADER | fetchAttributes::STRUCTURE | - fetchAttributes::IMPORTANCE)) - { + fetchAttributes::IMPORTANCE)) { + string contents; shared_ptr reader = file->getFileReader(); shared_ptr is = reader->getInputStream(); // Need whole message contents for structure - if (options.has(fetchAttributes::STRUCTURE)) - { + if (options.has(fetchAttributes::STRUCTURE)) { + byte_t buffer[16384]; contents.reserve(file->getLength()); - while (!is->eof()) - { + while (!is->eof()) { const size_t read = is->read(buffer, sizeof(buffer)); vmime::utility::stringUtils::appendBytesToString(contents, buffer, read); } - } + // Need only header - else - { + } else { + byte_t buffer[1024]; contents.reserve(4096); - while (!is->eof()) - { + while (!is->eof()) { + const size_t read = is->read(buffer, sizeof(buffer)); vmime::utility::stringUtils::appendBytesToString(contents, buffer, read); const size_t sep1 = contents.rfind("\r\n\r\n"); const size_t sep2 = contents.rfind("\n\n"); - if (sep1 != string::npos) - { + if (sep1 != string::npos) { contents.erase(contents.begin() + sep1 + 4, contents.end()); break; - } - else if (sep2 != string::npos) - { + } else if (sep2 != string::npos) { contents.erase(contents.begin() + sep2 + 2, contents.end()); break; } @@ -327,8 +361,7 @@ void maildirMessage::fetch(const shared_ptr & msgFolder, const fe msg.parse(contents); // Extract structure - if (options.has(fetchAttributes::STRUCTURE)) - { + if (options.has(fetchAttributes::STRUCTURE)) { m_structure = make_shared (shared_ptr (), msg); } @@ -336,25 +369,26 @@ void maildirMessage::fetch(const shared_ptr & msgFolder, const fe if (options.has(fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | fetchAttributes::FULL_HEADER | - fetchAttributes::IMPORTANCE)) - { + fetchAttributes::IMPORTANCE)) { + getOrCreateHeader()->copyFrom(*(msg.getHeader())); } } } -shared_ptr
maildirMessage::getOrCreateHeader() -{ - if (m_header != NULL) - return (m_header); - else +shared_ptr
maildirMessage::getOrCreateHeader() { + + if (m_header) { + return m_header; + } else { return (m_header = make_shared
()); + } } -shared_ptr maildirMessage::getParsedMessage() -{ +shared_ptr maildirMessage::getParsedMessage() { + std::ostringstream oss; utility::outputStreamAdapter os(oss); diff --git a/src/vmime/net/maildir/maildirMessage.hpp b/src/vmime/net/maildir/maildirMessage.hpp index 3e97a981..8cd0aac2 100644 --- a/src/vmime/net/maildir/maildirMessage.hpp +++ b/src/vmime/net/maildir/maildirMessage.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,9 +45,8 @@ class maildirFolder; /** maildir message implementation. */ +class VMIME_EXPORT maildirMessage : public message { -class VMIME_EXPORT maildirMessage : public message -{ friend class maildirFolder; maildirMessage(const maildirMessage&) : message() { } @@ -75,8 +74,22 @@ public: int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); - void extract(utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; - void extractPart(const shared_ptr & p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; + void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; + + void extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; void fetchPartHeader(const shared_ptr & p); @@ -90,7 +103,15 @@ private: shared_ptr
getOrCreateHeader(); - void extractImpl(utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, const size_t partialStart, const size_t partialLength, const bool peek) const; + void extractImpl( + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const size_t partialStart, + const size_t partialLength, + const bool peek + ) const; weak_ptr m_folder; diff --git a/src/vmime/net/maildir/maildirMessagePart.cpp b/src/vmime/net/maildir/maildirMessagePart.cpp index 787c0198..9d30e24d 100644 --- a/src/vmime/net/maildir/maildirMessagePart.cpp +++ b/src/vmime/net/maildir/maildirMessagePart.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,15 @@ namespace net { namespace maildir { -maildirMessagePart::maildirMessagePart(const shared_ptr & parent, const size_t number, const bodyPart& part) - : m_parent(parent), m_header(null), m_number(number) -{ +maildirMessagePart::maildirMessagePart( + const shared_ptr & parent, + const size_t number, + const bodyPart& part +) + : m_parent(parent), + m_header(null), + m_number(number) { + m_headerParsedOffset = part.getHeader()->getParsedOffset(); m_headerParsedLength = part.getHeader()->getParsedLength(); @@ -51,98 +57,104 @@ maildirMessagePart::maildirMessagePart(const shared_ptr & pa } -maildirMessagePart::~maildirMessagePart() -{ +maildirMessagePart::~maildirMessagePart() { + } -void maildirMessagePart::initStructure(const bodyPart& part) -{ - if (part.getBody()->getPartList().size() == 0) +void maildirMessagePart::initStructure(const bodyPart& part) { + + if (part.getBody()->getPartList().size() == 0) { + m_structure = null; - else - { - m_structure = make_shared - (dynamicCast (shared_from_this()), - part.getBody()->getPartList()); + + } else { + + m_structure = make_shared ( + dynamicCast (shared_from_this()), part.getBody()->getPartList() + ); } } -shared_ptr maildirMessagePart::getStructure() const -{ - if (m_structure != NULL) +shared_ptr maildirMessagePart::getStructure() const { + + if (m_structure) { return m_structure; - else + } else { return maildirMessageStructure::emptyStructure(); + } } -shared_ptr maildirMessagePart::getStructure() -{ - if (m_structure != NULL) +shared_ptr maildirMessagePart::getStructure() { + + if (m_structure) { return m_structure; - else + } else { return maildirMessageStructure::emptyStructure(); + } } -const mediaType& maildirMessagePart::getType() const -{ +const mediaType& maildirMessagePart::getType() const { + return m_mediaType; } -size_t maildirMessagePart::getSize() const -{ +size_t maildirMessagePart::getSize() const { + return m_size; } -size_t maildirMessagePart::getNumber() const -{ +size_t maildirMessagePart::getNumber() const { + return m_number; } -shared_ptr maildirMessagePart::getHeader() const -{ - if (m_header == NULL) +shared_ptr maildirMessagePart::getHeader() const { + + if (!m_header) { throw exceptions::unfetched_object(); - else + } else { return m_header; + } } -header& maildirMessagePart::getOrCreateHeader() -{ - if (m_header != NULL) +header& maildirMessagePart::getOrCreateHeader() { + + if (m_header) { return *m_header; - else + } else { return *(m_header = make_shared
()); + } } -size_t maildirMessagePart::getHeaderParsedOffset() const -{ +size_t maildirMessagePart::getHeaderParsedOffset() const { + return m_headerParsedOffset; } -size_t maildirMessagePart::getHeaderParsedLength() const -{ +size_t maildirMessagePart::getHeaderParsedLength() const { + return m_headerParsedLength; } -size_t maildirMessagePart::getBodyParsedOffset() const -{ +size_t maildirMessagePart::getBodyParsedOffset() const { + return m_bodyParsedOffset; } -size_t maildirMessagePart::getBodyParsedLength() const -{ +size_t maildirMessagePart::getBodyParsedLength() const { + return m_bodyParsedLength; } diff --git a/src/vmime/net/maildir/maildirMessagePart.hpp b/src/vmime/net/maildir/maildirMessagePart.hpp index 6aa80019..dd863a2b 100644 --- a/src/vmime/net/maildir/maildirMessagePart.hpp +++ b/src/vmime/net/maildir/maildirMessagePart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,7 +46,12 @@ class maildirMessagePart : public messagePart { public: - maildirMessagePart(const shared_ptr & parent, const size_t number, const bodyPart& part); + maildirMessagePart( + const shared_ptr & parent, + const size_t number, + const bodyPart& part + ); + ~maildirMessagePart(); diff --git a/src/vmime/net/maildir/maildirMessageStructure.cpp b/src/vmime/net/maildir/maildirMessageStructure.cpp index e01c2a92..1e2f2cc5 100644 --- a/src/vmime/net/maildir/maildirMessageStructure.cpp +++ b/src/vmime/net/maildir/maildirMessageStructure.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,11 @@ maildirMessageStructure::maildirMessageStructure() } -maildirMessageStructure::maildirMessageStructure(const shared_ptr & parent, const bodyPart& part) -{ +maildirMessageStructure::maildirMessageStructure( + const shared_ptr & parent, + const bodyPart& part +) { + shared_ptr mpart = make_shared (parent, 0, part); mpart->initStructure(part); @@ -53,10 +56,13 @@ maildirMessageStructure::maildirMessageStructure(const shared_ptr & parent, const std::vector >& list) -{ - for (size_t i = 0 ; i < list.size() ; ++i) - { +maildirMessageStructure::maildirMessageStructure( + const shared_ptr & parent, + const std::vector >& list +) { + + for (size_t i = 0 ; i < list.size() ; ++i) { + shared_ptr mpart = make_shared (parent, i, *list[i]); mpart->initStructure(*list[i]); @@ -65,27 +71,27 @@ maildirMessageStructure::maildirMessageStructure(const shared_ptr maildirMessageStructure::getPartAt(const size_t x) const -{ +shared_ptr maildirMessageStructure::getPartAt(const size_t x) const { + return m_parts[x]; } -shared_ptr maildirMessageStructure::getPartAt(const size_t x) -{ +shared_ptr maildirMessageStructure::getPartAt(const size_t x) { + return m_parts[x]; } -size_t maildirMessageStructure::getPartCount() const -{ +size_t maildirMessageStructure::getPartCount() const { + return m_parts.size(); } // static -shared_ptr maildirMessageStructure::emptyStructure() -{ +shared_ptr maildirMessageStructure::emptyStructure() { + return m_emptyStructure; } diff --git a/src/vmime/net/maildir/maildirMessageStructure.hpp b/src/vmime/net/maildir/maildirMessageStructure.hpp index fce5db6f..1a20ea45 100644 --- a/src/vmime/net/maildir/maildirMessageStructure.hpp +++ b/src/vmime/net/maildir/maildirMessageStructure.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,13 +42,19 @@ namespace maildir { class maildirMessagePart; -class maildirMessageStructure : public messageStructure -{ +class maildirMessageStructure : public messageStructure { + public: maildirMessageStructure(); - maildirMessageStructure(const shared_ptr & parent, const bodyPart& part); - maildirMessageStructure(const shared_ptr & parent, const std::vector >& list); + maildirMessageStructure( + const shared_ptr & parent, + const bodyPart& part + ); + maildirMessageStructure( + const shared_ptr & parent, + const std::vector >& list + ); shared_ptr getPartAt(const size_t x) const; diff --git a/src/vmime/net/maildir/maildirServiceInfos.cpp b/src/vmime/net/maildir/maildirServiceInfos.cpp index 974a0c21..f9d92d37 100644 --- a/src/vmime/net/maildir/maildirServiceInfos.cpp +++ b/src/vmime/net/maildir/maildirServiceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,21 +35,20 @@ namespace net { namespace maildir { -maildirServiceInfos::maildirServiceInfos() -{ +maildirServiceInfos::maildirServiceInfos() { + } -const string maildirServiceInfos::getPropertyPrefix() const -{ +const string maildirServiceInfos::getPropertyPrefix() const { + return "store.maildir."; } -const maildirServiceInfos::props& maildirServiceInfos::getProperties() const -{ - static props maildirProps = - { +const maildirServiceInfos::props& maildirServiceInfos::getProperties() const { + + static props maildirProps = { property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED) }; @@ -57,8 +56,8 @@ const maildirServiceInfos::props& maildirServiceInfos::getProperties() const } -const std::vector maildirServiceInfos::getAvailableProperties() const -{ +const std::vector maildirServiceInfos::getAvailableProperties() const { + std::vector list; const props& p = getProperties(); diff --git a/src/vmime/net/maildir/maildirServiceInfos.hpp b/src/vmime/net/maildir/maildirServiceInfos.hpp index 70ddc6dc..827a7d78 100644 --- a/src/vmime/net/maildir/maildirServiceInfos.hpp +++ b/src/vmime/net/maildir/maildirServiceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,13 @@ namespace maildir { /** Information about maildir service. */ +class VMIME_EXPORT maildirServiceInfos : public serviceInfos { -class VMIME_EXPORT maildirServiceInfos : public serviceInfos -{ public: maildirServiceInfos(); - struct props - { + struct props { serviceInfos::property PROPERTY_SERVER_ROOTPATH; }; diff --git a/src/vmime/net/maildir/maildirStore.cpp b/src/vmime/net/maildir/maildirStore.cpp index 4029eb7d..a994f45c 100644 --- a/src/vmime/net/maildir/maildirStore.cpp +++ b/src/vmime/net/maildir/maildirStore.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,90 +52,112 @@ namespace net { namespace maildir { -maildirStore::maildirStore(const shared_ptr & sess, const shared_ptr & auth) - : store(sess, getInfosInstance(), auth), m_connected(false) -{ +maildirStore::maildirStore( + const shared_ptr & sess, + const shared_ptr & auth +) + : store(sess, getInfosInstance(), auth), + m_connected(false) { + } -maildirStore::~maildirStore() -{ - try - { - if (isConnected()) +maildirStore::~maildirStore() { + + try { + + if (isConnected()) { disconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -const string maildirStore::getProtocolName() const -{ +const string maildirStore::getProtocolName() const { + return "maildir"; } -shared_ptr maildirStore::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr maildirStore::getRootFolder() { - return shared_ptr - (new maildirFolder(folder::path(), - dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new maildirFolder( + folder::path(), + dynamicCast (shared_from_this()) + ) + ); } -shared_ptr maildirStore::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr maildirStore::getDefaultFolder() { - return shared_ptr - (new maildirFolder(folder::path::component("inbox"), - dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new maildirFolder( + folder::path::component("inbox"), + dynamicCast (shared_from_this()) + ) + ); } -shared_ptr maildirStore::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr maildirStore::getFolder(const folder::path& path) { - return shared_ptr - (new maildirFolder(path, dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new maildirFolder( + path, + dynamicCast (shared_from_this()) + ) + ); } -bool maildirStore::isValidFolderName(const folder::path::component& name) const -{ - if (!platform::getHandler()->getFileSystemFactory()->isValidPathComponent(name)) +bool maildirStore::isValidFolderName(const folder::path::component& name) const { + + if (!platform::getHandler()->getFileSystemFactory()->isValidPathComponent(name)) { return false; + } const string& buf = name.getBuffer(); // Name cannot start/end with spaces - if (utility::stringUtils::trim(buf) != buf) + if (utility::stringUtils::trim(buf) != buf) { return false; + } // Name cannot start with '.' const size_t length = buf.length(); size_t pos = 0; - while ((pos < length) && (buf[pos] == '.')) + while ((pos < length) && (buf[pos] == '.')) { ++pos; + } return (pos == 0); } -void maildirStore::connect() -{ - if (isConnected()) +void maildirStore::connect() { + + if (isConnected()) { throw exceptions::already_connected(); + } // Get root directory shared_ptr fsf = platform::getHandler()->getFileSystemFactory(); @@ -145,14 +167,11 @@ void maildirStore::connect() shared_ptr rootDir = fsf->create(m_fsPath); // Try to create the root directory if it does not exist - if (!(rootDir->exists() && rootDir->isDirectory())) - { - try - { + if (!(rootDir->exists() && rootDir->isDirectory())) { + + try { rootDir->createDirectory(); - } - catch (exceptions::filesystem_exception& e) - { + } catch (exceptions::filesystem_exception& e) { throw exceptions::connection_error("Cannot create root directory.", e); } } @@ -163,29 +182,29 @@ void maildirStore::connect() } -bool maildirStore::isConnected() const -{ - return (m_connected); +bool maildirStore::isConnected() const { + + return m_connected; } -bool maildirStore::isSecuredConnection() const -{ +bool maildirStore::isSecuredConnection() const { + return false; } -shared_ptr maildirStore::getConnectionInfos() const -{ +shared_ptr maildirStore::getConnectionInfos() const { + return make_shared ("localhost", static_cast (0)); } -void maildirStore::disconnect() -{ +void maildirStore::disconnect() { + for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { + it != m_folders.end() ; ++it) { + (*it)->onStoreDisconnected(); } @@ -195,53 +214,56 @@ void maildirStore::disconnect() } -void maildirStore::noop() -{ +void maildirStore::noop() { + // Nothing to do. } -shared_ptr maildirStore::getFormat() -{ +shared_ptr maildirStore::getFormat() { + return m_format; } -shared_ptr maildirStore::getFormat() const -{ +shared_ptr maildirStore::getFormat() const { + return m_format; } -void maildirStore::registerFolder(maildirFolder* folder) -{ +void maildirStore::registerFolder(maildirFolder* folder) { + m_folders.push_back(folder); } -void maildirStore::unregisterFolder(maildirFolder* folder) -{ +void maildirStore::unregisterFolder(maildirFolder* folder) { + std::list ::iterator it = std::find(m_folders.begin(), m_folders.end(), folder); - if (it != m_folders.end()) m_folders.erase(it); + + if (it != m_folders.end()) { + m_folders.erase(it); + } } -const utility::path& maildirStore::getFileSystemPath() const -{ - return (m_fsPath); +const utility::path& maildirStore::getFileSystemPath() const { + + return m_fsPath; } -int maildirStore::getCapabilities() const -{ - return (CAPABILITY_CREATE_FOLDER | - CAPABILITY_RENAME_FOLDER | - CAPABILITY_ADD_MESSAGE | - CAPABILITY_COPY_MESSAGE | - CAPABILITY_DELETE_MESSAGE | - CAPABILITY_PARTIAL_FETCH | - CAPABILITY_MESSAGE_FLAGS | - CAPABILITY_EXTRACT_PART); +int maildirStore::getCapabilities() const { + + return CAPABILITY_CREATE_FOLDER | + CAPABILITY_RENAME_FOLDER | + CAPABILITY_ADD_MESSAGE | + CAPABILITY_COPY_MESSAGE | + CAPABILITY_DELETE_MESSAGE | + CAPABILITY_PARTIAL_FETCH | + CAPABILITY_MESSAGE_FLAGS | + CAPABILITY_EXTRACT_PART; } @@ -251,14 +273,14 @@ int maildirStore::getCapabilities() const maildirServiceInfos maildirStore::sm_infos; -const serviceInfos& maildirStore::getInfosInstance() -{ +const serviceInfos& maildirStore::getInfosInstance() { + return sm_infos; } -const serviceInfos& maildirStore::getInfos() const -{ +const serviceInfos& maildirStore::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/maildir/maildirStore.hpp b/src/vmime/net/maildir/maildirStore.hpp index ba7b8c13..13255c0a 100644 --- a/src/vmime/net/maildir/maildirStore.hpp +++ b/src/vmime/net/maildir/maildirStore.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -53,14 +53,17 @@ class maildirFolder; /** maildir store service. */ +class VMIME_EXPORT maildirStore : public store { -class VMIME_EXPORT maildirStore : public store -{ friend class maildirFolder; public: - maildirStore(const shared_ptr & sess, const shared_ptr & auth); + maildirStore( + const shared_ptr & sess, + const shared_ptr & auth + ); + ~maildirStore(); const string getProtocolName() const; diff --git a/src/vmime/net/maildir/maildirUtils.cpp b/src/vmime/net/maildir/maildirUtils.cpp index 1c75805a..9942e56e 100644 --- a/src/vmime/net/maildir/maildirUtils.cpp +++ b/src/vmime/net/maildir/maildirUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,17 +41,17 @@ namespace net { namespace maildir { -bool maildirUtils::isMessageFile(const utility::file& file) -{ +bool maildirUtils::isMessageFile(const utility::file& file) { + // Ignore files which name begins with '.' if (file.isFile() && file.getFullPath().getLastComponent().getBuffer().length() >= 1 && - file.getFullPath().getLastComponent().getBuffer()[0] != '.') - { - return (true); + file.getFullPath().getLastComponent().getBuffer()[0] != '.') { + + return true; } - return (false); + return false; } @@ -68,28 +68,28 @@ bool maildirUtils::isMessageFile(const utility::file& file) // characters when reading file names. -const utility::file::path::component maildirUtils::extractId - (const utility::file::path::component& filename) -{ +const utility::file::path::component maildirUtils::extractId( + const utility::file::path::component& filename +) { + size_t sep = filename.getBuffer().rfind(':'); // try colon - if (sep == string::npos) - { + if (sep == string::npos) { sep = filename.getBuffer().rfind('-'); // try dash (Windows) if (sep == string::npos) return (filename); } - return (utility::path::component - (string(filename.getBuffer().begin(), filename.getBuffer().begin() + sep))); + return utility::path::component( + string(filename.getBuffer().begin(), filename.getBuffer().begin() + sep) + ); } -int maildirUtils::extractFlags(const utility::file::path::component& comp) -{ +int maildirUtils::extractFlags(const utility::file::path::component& comp) { + size_t sep = comp.getBuffer().rfind(':'); // try colon - if (sep == string::npos) - { + if (sep == string::npos) { sep = comp.getBuffer().rfind('-'); // try dash (Windows) if (sep == string::npos) return 0; } @@ -99,25 +99,24 @@ int maildirUtils::extractFlags(const utility::file::path::component& comp) int flags = 0; - for (size_t i = 0 ; i < count ; ++i) - { - switch (flagsString[i]) - { - case 'R': case 'r': flags |= message::FLAG_REPLIED; break; - case 'S': case 's': flags |= message::FLAG_SEEN; break; - case 'T': case 't': flags |= message::FLAG_DELETED; break; - case 'F': case 'f': flags |= message::FLAG_MARKED; break; - case 'P': case 'p': flags |= message::FLAG_PASSED; break; - case 'D': case 'd': flags |= message::FLAG_DRAFT; break; + for (size_t i = 0 ; i < count ; ++i) { + + switch (flagsString[i]) { + case 'R': case 'r': flags |= message::FLAG_REPLIED; break; + case 'S': case 's': flags |= message::FLAG_SEEN; break; + case 'T': case 't': flags |= message::FLAG_DELETED; break; + case 'F': case 'f': flags |= message::FLAG_MARKED; break; + case 'P': case 'p': flags |= message::FLAG_PASSED; break; + case 'D': case 'd': flags |= message::FLAG_DRAFT; break; } } - return (flags); + return flags; } -const utility::file::path::component maildirUtils::buildFlags(const int flags) -{ +const utility::file::path::component maildirUtils::buildFlags(const int flags) { + string str; str.reserve(8); @@ -130,24 +129,28 @@ const utility::file::path::component maildirUtils::buildFlags(const int flags) if (flags & message::FLAG_DELETED) str += "T"; if (flags & message::FLAG_DRAFT) str += "D"; - return (utility::file::path::component(str)); + return utility::file::path::component(str); } -const utility::file::path::component maildirUtils::buildFilename - (const utility::file::path::component& id, const int flags) -{ - if (flags == message::FLAG_RECENT) +const utility::file::path::component maildirUtils::buildFilename( + const utility::file::path::component& id, + const int flags +) { + + if (flags == message::FLAG_RECENT) { return id; - else - return (buildFilename(id, buildFlags(flags))); + } else { + return buildFilename(id, buildFlags(flags)); + } } -const utility::file::path::component maildirUtils::buildFilename - (const utility::file::path::component& id, - const utility::file::path::component& flags) -{ +const utility::file::path::component maildirUtils::buildFilename( + const utility::file::path::component& id, + const utility::file::path::component& flags +) { + #if VMIME_PLATFORM_IS_WINDOWS static const char DELIMITER[] = "-"; #else @@ -158,8 +161,8 @@ const utility::file::path::component maildirUtils::buildFilename } -const utility::file::path::component maildirUtils::generateId() -{ +const utility::file::path::component maildirUtils::generateId() { + std::ostringstream oss; oss.imbue(std::locale::classic()); @@ -171,70 +174,64 @@ const utility::file::path::component maildirUtils::generateId() oss << "."; oss << platform::getHandler()->getHostName(); - return (utility::file::path::component(oss.str())); + return utility::file::path::component(oss.str()); } -void maildirUtils::recursiveFSDelete(const shared_ptr & dir) -{ +void maildirUtils::recursiveFSDelete(const shared_ptr & dir) { + shared_ptr files = dir->getFiles(); // First, delete files and subdirectories in this directory - while (files->hasMoreElements()) - { + while (files->hasMoreElements()) { + shared_ptr file = files->nextElement(); - if (file->isDirectory()) - { + if (file->isDirectory()) { + maildirUtils::recursiveFSDelete(file); - } - else - { - try - { + + } else { + + try { file->remove(); - } - catch (exceptions::filesystem_exception&) - { + } catch (exceptions::filesystem_exception&) { // Ignore } } } // Then, delete this (empty) directory - try - { + try { dir->remove(); - } - catch (exceptions::filesystem_exception&) - { + } catch (exceptions::filesystem_exception&) { // Ignore } } -class maildirMessageSetEnumerator : public messageSetEnumerator -{ +class maildirMessageSetEnumerator : public messageSetEnumerator { + public: maildirMessageSetEnumerator(const size_t msgCount) - : m_msgCount(msgCount) - { + : m_msgCount(msgCount) { } - void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) - { + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { + size_t last = range.getLast(); if (last == size_t(-1)) last = m_msgCount; - for (size_t i = range.getFirst() ; i <= last ; ++i) + for (size_t i = range.getFirst() ; i <= last ; ++i) { list.push_back(i); + } } - void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) - { + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) { + // Not supported } @@ -249,8 +246,11 @@ private: // static -const std::vector maildirUtils::messageSetToNumberList(const messageSet& msgs, const size_t msgCount) -{ +const std::vector maildirUtils::messageSetToNumberList( + const messageSet& msgs, + const size_t msgCount +) { + maildirMessageSetEnumerator en(msgCount); msgs.enumerate(en); @@ -263,17 +263,19 @@ const std::vector maildirUtils::messageSetToNumberList(const messageSet // messageIdComparator // -maildirUtils::messageIdComparator::messageIdComparator - (const utility::file::path::component& comp) - : m_comp(maildirUtils::extractId(comp)) -{ +maildirUtils::messageIdComparator::messageIdComparator( + const utility::file::path::component& comp +) + : m_comp(maildirUtils::extractId(comp)) { + } -bool maildirUtils::messageIdComparator::operator() - (const utility::file::path::component& other) const -{ - return (m_comp == maildirUtils::extractId(other)); +bool maildirUtils::messageIdComparator::operator()( + const utility::file::path::component& other +) const { + + return m_comp == maildirUtils::extractId(other); } diff --git a/src/vmime/net/maildir/maildirUtils.hpp b/src/vmime/net/maildir/maildirUtils.hpp index 6f120636..94ab9983 100644 --- a/src/vmime/net/maildir/maildirUtils.hpp +++ b/src/vmime/net/maildir/maildirUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,16 +47,15 @@ class maildirStore; /** Miscellaneous helpers functions for maildir messaging system. */ +class VMIME_EXPORT maildirUtils { -class VMIME_EXPORT maildirUtils -{ public: /** Comparator for message filenames, based only on the * unique identifier part of the filename. */ - class messageIdComparator - { + class messageIdComparator { + public: messageIdComparator(const utility::file::path::component& comp); @@ -110,7 +109,10 @@ public: * @param flags flags part of the filename * @return message filename */ - static const utility::file::path::component buildFilename(const utility::file::path::component& id, const utility::file::path::component& flags); + static const utility::file::path::component buildFilename( + const utility::file::path::component& id, + const utility::file::path::component& flags + ); /** Build a filename with the specified id and flags. * @@ -118,7 +120,10 @@ public: * @param flags set of flags * @return message filename */ - static const utility::file::path::component buildFilename(const utility::file::path::component& id, const int flags); + static const utility::file::path::component buildFilename( + const utility::file::path::component& id, + const int flags + ); /** Generate a new unique message identifier. * @@ -138,7 +143,10 @@ public: * @param msgCount number of messages in folder * @return list of message numbers */ - static const std::vector messageSetToNumberList(const messageSet& msgs, const size_t msgCount); + static const std::vector messageSetToNumberList( + const messageSet& msgs, + const size_t msgCount + ); }; diff --git a/src/vmime/net/message.cpp b/src/vmime/net/message.cpp index 1a0c8c2c..2d6f995a 100644 --- a/src/vmime/net/message.cpp +++ b/src/vmime/net/message.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,20 +41,20 @@ string messagePart::getName() const return {}; } -shared_ptr messagePart::getPartAt(const size_t pos) const -{ +shared_ptr messagePart::getPartAt(const size_t pos) const { + return getStructure()->getPartAt(pos); } -shared_ptr messagePart::getPartAt(const size_t pos) -{ +shared_ptr messagePart::getPartAt(const size_t pos) { + return getStructure()->getPartAt(pos); } -size_t messagePart::getPartCount() const -{ +size_t messagePart::getPartCount() const { + return getStructure()->getPartCount(); } @@ -63,19 +63,19 @@ size_t messagePart::getPartCount() const // message::uid -message::uid::uid() -{ +message::uid::uid() { + } message::uid::uid(const string& uid) - : m_str(uid) -{ + : m_str(uid) { + } -message::uid::uid(const unsigned long uid) -{ +message::uid::uid(const unsigned long uid) { + std::ostringstream oss; oss.imbue(std::locale::classic()); oss << uid; @@ -85,33 +85,33 @@ message::uid::uid(const unsigned long uid) message::uid::uid(const char* uid) - : m_str(uid) -{ + : m_str(uid) { + } -message::uid::uid(const uid& other) -{ +message::uid::uid(const uid& other) { + m_str = other.m_str; } -message::uid& message::uid::operator=(const uid& other) -{ +message::uid& message::uid::operator=(const uid& other) { + m_str = other.m_str; return *this; } -message::uid& message::uid::operator=(const string& uid) -{ +message::uid& message::uid::operator=(const string& uid) { + m_str = uid; return *this; } -message::uid& message::uid::operator=(const unsigned long uid) -{ +message::uid& message::uid::operator=(const unsigned long uid) { + std::ostringstream oss; oss.imbue(std::locale::classic()); oss << uid; @@ -122,26 +122,26 @@ message::uid& message::uid::operator=(const unsigned long uid) } -message::uid::operator string() const -{ +message::uid::operator string() const { + return m_str; } -bool message::uid::empty() const -{ +bool message::uid::empty() const { + return m_str.empty(); } -bool message::uid::operator==(const uid& other) const -{ +bool message::uid::operator==(const uid& other) const { + return m_str == other.m_str; } -std::ostream& operator<<(std::ostream& os, const message::uid& uid) -{ +std::ostream& operator<<(std::ostream& os, const message::uid& uid) { + os << static_cast (uid); return os; } diff --git a/src/vmime/net/message.hpp b/src/vmime/net/message.hpp index 68cce415..c0a2839b 100644 --- a/src/vmime/net/message.hpp +++ b/src/vmime/net/message.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,13 +49,12 @@ class messageStructure; /** A MIME part in a message. */ +class VMIME_EXPORT messagePart : public object, public enable_shared_from_this { -class VMIME_EXPORT messagePart : public object, public enable_shared_from_this -{ protected: messagePart() { } - messagePart(const messagePart&) : object(), enable_shared_from_this () { } + messagePart(const messagePart&); virtual ~messagePart() { } @@ -100,13 +99,13 @@ public: virtual size_t getNumber() const = 0; /** Return the name of this part. In particular, this corresponds to - * the attachment file name for attachment parts. - * - * The part name may be empty if the part does not advertise it or - * if the underlying protocol does not support it. - * - * @return part name - */ + * the attachment file name for attachment parts. + * + * The part name may be empty if the part does not advertise it or + * if the underlying protocol does not support it. + * + * @return part name + */ virtual string getName() const; /** Return the sub-part at the specified position (zero is the @@ -135,13 +134,12 @@ public: /** Structure of a MIME part/message. */ +class VMIME_EXPORT messageStructure : public object, public enable_shared_from_this { -class VMIME_EXPORT messageStructure : public object, public enable_shared_from_this -{ protected: messageStructure() { } - messageStructure(const messageStructure&) : object(), enable_shared_from_this () { } + messageStructure(const messageStructure&); public: @@ -173,28 +171,24 @@ public: /** Abstract representation of a message in a store/transport service. */ +class VMIME_EXPORT message : public object, public enable_shared_from_this { -class VMIME_EXPORT message : public object, public enable_shared_from_this -{ protected: message() { } - message(const message&) : object(), enable_shared_from_this () { } + message(const message&); - enum PrivateConstants - { + enum PrivateConstants { FLAG_UNDEFINED = 9999 /**< Used internally to indicate flags have not been initialized yet. */ }; public: - virtual ~message() { } - /** The type for an unique message identifier. */ - class VMIME_EXPORT uid - { + class VMIME_EXPORT uid { + public: uid(); @@ -265,8 +259,7 @@ public: /** Possible flags for a message. */ - enum Flags - { + enum Flags { FLAG_SEEN = (1 << 0), /**< Message has been seen. */ FLAG_RECENT = (1 << 1), /**< Message has been recently received. */ FLAG_DELETED = (1 << 2), /**< Message is marked for deletion. */ @@ -278,8 +271,7 @@ public: /** Methods for setting the flags. */ - enum FlagsModes - { + enum FlagsModes { FLAG_MODE_SET, /**< Set (replace) the flags. */ FLAG_MODE_ADD, /**< Add the flags. */ FLAG_MODE_REMOVE /**< Remove the flags. */ @@ -310,12 +302,13 @@ public: * be supported by the protocol (IMAP supports this), but it will NOT throw * an exception if not supported. */ - virtual void extract - (utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, - const size_t length = -1, - const bool peek = false) const = 0; + virtual void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const = 0; /** Extract the specified MIME part of the message (header + contents). * @@ -330,13 +323,14 @@ public: * be supported by the protocol (IMAP supports this), but it will NOT throw * an exception if not supported. */ - virtual void extractPart - (const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, - const size_t length = -1, - const bool peek = false) const = 0; + virtual void extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const = 0; /** Fetch the MIME header for the specified part. * diff --git a/src/vmime/net/messageSet.cpp b/src/vmime/net/messageSet.cpp index e30ebc5c..654da413 100644 --- a/src/vmime/net/messageSet.cpp +++ b/src/vmime/net/messageSet.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,62 +40,68 @@ namespace net { // messageRange -messageRange::messageRange() -{ +messageRange::messageRange() { + } -messageRange::~messageRange() -{ +messageRange::~messageRange() { + } // numberMessageRange numberMessageRange::numberMessageRange(const size_t number) - : m_first(number), m_last(number) -{ - if (number < 1) + : m_first(number), + m_last(number) { + + if (number < 1) { throw std::invalid_argument("number"); + } } numberMessageRange::numberMessageRange(const size_t first, const size_t last) - : m_first(first), m_last(last) -{ - if (first < 1 || first == static_cast (-1)) + : m_first(first), + m_last(last) { + + if (first < 1 || first == static_cast (-1)) { throw std::invalid_argument("first"); - else if (last != static_cast (-1) && last < first) + } else if (last != static_cast (-1) && last < first) { throw std::invalid_argument("last"); + } } numberMessageRange::numberMessageRange(const numberMessageRange& other) - : messageRange(), m_first(other.m_first), m_last(other.m_last) -{ + : messageRange(), + m_first(other.m_first), + m_last(other.m_last) { + } -size_t numberMessageRange::getFirst() const -{ +size_t numberMessageRange::getFirst() const { + return m_first; } -size_t numberMessageRange::getLast() const -{ +size_t numberMessageRange::getLast() const { + return m_last; } -void numberMessageRange::enumerate(messageSetEnumerator& en) const -{ +void numberMessageRange::enumerate(messageSetEnumerator& en) const { + en.enumerateNumberMessageRange(*this); } -messageRange* numberMessageRange::clone() const -{ +messageRange* numberMessageRange::clone() const { + return new numberMessageRange(*this); } @@ -103,43 +109,47 @@ messageRange* numberMessageRange::clone() const // UIDMessageRange UIDMessageRange::UIDMessageRange(const message::uid& uid) - : m_first(uid), m_last(uid) -{ + : m_first(uid), + m_last(uid) { + } UIDMessageRange::UIDMessageRange(const message::uid& first, const message::uid& last) - : m_first(first), m_last(last) -{ + : m_first(first), + m_last(last) { + } UIDMessageRange::UIDMessageRange(const UIDMessageRange& other) - : messageRange(), m_first(other.m_first), m_last(other.m_last) -{ + : messageRange(), + m_first(other.m_first), + m_last(other.m_last) { + } -const message::uid UIDMessageRange::getFirst() const -{ +const message::uid UIDMessageRange::getFirst() const { + return m_first; } -const message::uid UIDMessageRange::getLast() const -{ +const message::uid UIDMessageRange::getLast() const { + return m_last; } -void UIDMessageRange::enumerate(messageSetEnumerator& en) const -{ +void UIDMessageRange::enumerate(messageSetEnumerator& en) const { + en.enumerateUIDMessageRange(*this); } -messageRange* UIDMessageRange::clone() const -{ +messageRange* UIDMessageRange::clone() const { + return new UIDMessageRange(*this); } @@ -147,38 +157,40 @@ messageRange* UIDMessageRange::clone() const // messageSet -messageSet::messageSet() -{ +messageSet::messageSet() { + } messageSet::messageSet(const messageSet& other) - : object() -{ + : object() { + m_ranges.resize(other.m_ranges.size()); - for (size_t i = 0, n = other.m_ranges.size() ; i < n ; ++i) + for (size_t i = 0, n = other.m_ranges.size() ; i < n ; ++i) { m_ranges[i] = other.m_ranges[i]->clone(); + } } -messageSet::~messageSet() -{ - for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i) +messageSet::~messageSet() { + + for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i) { delete m_ranges[i]; + } } // static -messageSet messageSet::empty() -{ +messageSet messageSet::empty() { + return messageSet(); } // static -messageSet messageSet::byNumber(const size_t number) -{ +messageSet messageSet::byNumber(const size_t number) { + messageSet set; set.m_ranges.push_back(new numberMessageRange(number)); @@ -187,8 +199,8 @@ messageSet messageSet::byNumber(const size_t number) // static -messageSet messageSet::byNumber(const size_t first, const size_t last) -{ +messageSet messageSet::byNumber(const size_t first, const size_t last) { + messageSet set; set.m_ranges.push_back(new numberMessageRange(first, last)); @@ -197,8 +209,8 @@ messageSet messageSet::byNumber(const size_t first, const size_t last) // static -messageSet messageSet::byNumber(const std::vector & numbers) -{ +messageSet messageSet::byNumber(const std::vector & numbers) { + // Sort a copy of the list std::vector sortedNumbers; @@ -212,29 +224,31 @@ messageSet messageSet::byNumber(const std::vector & numbers) messageSet set; for (std::vector ::const_iterator it = sortedNumbers.begin() ; - it != sortedNumbers.end() ; ++it) - { + it != sortedNumbers.end() ; ++it) { + const size_t current = *it; - if (current == previous) + if (current == previous) { continue; // skip duplicates + } - if (current == static_cast (-1)) + if (current == static_cast (-1)) { throw std::invalid_argument("numbers"); + } + + if (previous == static_cast (-1)) { - if (previous == static_cast (-1)) - { previous = current; rangeStart = current; - } - else - { - if (current == previous + 1) - { + + } else { + + if (current == previous + 1) { + previous = current; - } - else - { + + } else { + set.m_ranges.push_back(new numberMessageRange(rangeStart, previous)); previous = current; @@ -250,8 +264,8 @@ messageSet messageSet::byNumber(const std::vector & numbers) // static -messageSet messageSet::byUID(const message::uid& uid) -{ +messageSet messageSet::byUID(const message::uid& uid) { + messageSet set; set.m_ranges.push_back(new UIDMessageRange(uid)); @@ -259,8 +273,8 @@ messageSet messageSet::byUID(const message::uid& uid) } -messageSet messageSet::byUID(const message::uid& first, const message::uid& last) -{ +messageSet messageSet::byUID(const message::uid& first, const message::uid& last) { + messageSet set; set.m_ranges.push_back(new UIDMessageRange(first, last)); @@ -268,27 +282,29 @@ messageSet messageSet::byUID(const message::uid& first, const message::uid& last } -messageSet messageSet::byUID(const std::vector & uids) -{ +messageSet messageSet::byUID(const std::vector & uids) { + std::vector numericUIDs; - for (size_t i = 0, n = uids.size() ; i < n ; ++i) - { + for (size_t i = 0, n = uids.size() ; i < n ; ++i) { + const string uid = uids[i]; int numericUID = 0; const char* p = uid.c_str(); - for ( ; *p >= '0' && *p <= '9' ; ++p) - numericUID = (numericUID * 10) + (*p - '0'); + for ( ; *p >= '0' && *p <= '9' ; ++p) { + numericUID = (numericUID * 10) + (*p - '0'); + } + + if (*p != '\0') { - if (*p != '\0') - { messageSet set; // Non-numeric UID, fall back to plain UID list (single-UID ranges) - for (size_t i = 0, n = uids.size() ; i < n ; ++i) + for (size_t i = 0, n = uids.size() ; i < n ; ++i) { set.m_ranges.push_back(new UIDMessageRange(uids[i])); + } return set; } @@ -309,29 +325,33 @@ messageSet messageSet::byUID(const std::vector & uids) messageSet set; for (std::vector ::const_iterator it = sortedUIDs.begin() ; - it != sortedUIDs.end() ; ++it) - { + it != sortedUIDs.end() ; ++it) { + const vmime_uint32 current = *it; - if (current == previous) + if (current == previous) { continue; // skip duplicates + } + + if (previous == static_cast (-1)) { - if (previous == static_cast (-1)) - { previous = current; rangeStart = current; - } - else - { - if (current == previous + 1) - { + + } else { + + if (current == previous + 1) { + previous = current; - } - else - { - set.m_ranges.push_back(new UIDMessageRange - (utility::stringUtils::toString(rangeStart), - utility::stringUtils::toString(previous))); + + } else { + + set.m_ranges.push_back( + new UIDMessageRange( + utility::stringUtils::toString(rangeStart), + utility::stringUtils::toString(previous) + ) + ); previous = current; rangeStart = current; @@ -339,56 +359,61 @@ messageSet messageSet::byUID(const std::vector & uids) } } - set.m_ranges.push_back(new UIDMessageRange - (utility::stringUtils::toString(rangeStart), - utility::stringUtils::toString(previous))); + set.m_ranges.push_back( + new UIDMessageRange( + utility::stringUtils::toString(rangeStart), + utility::stringUtils::toString(previous) + ) + ); return set; } -void messageSet::addRange(const messageRange& range) -{ - if (!m_ranges.empty() && typeid(*m_ranges[0]) != typeid(range)) +void messageSet::addRange(const messageRange& range) { + + if (!m_ranges.empty() && typeid(*m_ranges[0]) != typeid(range)) { throw std::invalid_argument("range"); + } m_ranges.push_back(range.clone()); } -void messageSet::enumerate(messageSetEnumerator& en) const -{ - for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i) +void messageSet::enumerate(messageSetEnumerator& en) const { + + for (size_t i = 0, n = m_ranges.size() ; i < n ; ++i) { m_ranges[i]->enumerate(en); + } } -bool messageSet::isEmpty() const -{ +bool messageSet::isEmpty() const { + return m_ranges.empty(); } -bool messageSet::isNumberSet() const -{ +bool messageSet::isNumberSet() const { + return !isEmpty() && dynamic_cast (m_ranges[0]) != NULL; } -bool messageSet::isUIDSet() const -{ +bool messageSet::isUIDSet() const { + return !isEmpty() && dynamic_cast (m_ranges[0]) != NULL; } -size_t messageSet::getRangeCount() const -{ +size_t messageSet::getRangeCount() const { + return m_ranges.size(); } -const messageRange& messageSet::getRangeAt(const size_t i) const -{ +const messageRange& messageSet::getRangeAt(const size_t i) const { + return *m_ranges[i]; } diff --git a/src/vmime/net/messageSet.hpp b/src/vmime/net/messageSet.hpp index 1be49761..8b33b0dd 100644 --- a/src/vmime/net/messageSet.hpp +++ b/src/vmime/net/messageSet.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,9 +46,8 @@ class UIDMessageRange; /** Enumerator used to retrieve the message number/UID ranges contained * in a messageSet object. */ +class VMIME_EXPORT messageSetEnumerator { -class VMIME_EXPORT messageSetEnumerator -{ public: virtual void enumerateNumberMessageRange(const numberMessageRange& range) = 0; @@ -59,9 +58,8 @@ public: /** A range of (continuous) messages, designated either by their * sequence number, or by their UID. */ +class VMIME_EXPORT messageRange : public object { -class VMIME_EXPORT messageRange : public object -{ public: virtual ~messageRange(); @@ -86,9 +84,8 @@ protected: /** A range of (continuous) messages designated by their sequence number. */ +class VMIME_EXPORT numberMessageRange : public messageRange { -class VMIME_EXPORT numberMessageRange : public messageRange -{ public: /** Constructs a message range containing a single message. @@ -137,9 +134,8 @@ private: /** A range of (continuous) messages represented by their UID. */ +class VMIME_EXPORT UIDMessageRange : public messageRange { -class VMIME_EXPORT UIDMessageRange : public messageRange -{ public: /** Constructs a message range containing a single message. @@ -211,9 +207,8 @@ private: * vmime::net::messageSet::byUID(1000, "*") * \endcode */ +class VMIME_EXPORT messageSet : public object { -class VMIME_EXPORT messageSet : public object -{ public: ~messageSet(); diff --git a/src/vmime/net/pop3/POP3Command.cpp b/src/vmime/net/pop3/POP3Command.cpp index 528746e0..0e798884 100644 --- a/src/vmime/net/pop3/POP3Command.cpp +++ b/src/vmime/net/pop3/POP3Command.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,28 +43,29 @@ namespace pop3 { POP3Command::POP3Command(const string& text, const string& traceText) - : m_text(text), m_traceText(traceText) -{ + : m_text(text), + m_traceText(traceText) { + } // static -shared_ptr POP3Command::CAPA() -{ +shared_ptr POP3Command::CAPA() { + return createCommand("CAPA"); } // static -shared_ptr POP3Command::NOOP() -{ +shared_ptr POP3Command::NOOP() { + return createCommand("NOOP"); } // static -shared_ptr POP3Command::AUTH(const string& mechName) -{ +shared_ptr POP3Command::AUTH(const string& mechName) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTH " << mechName; @@ -74,8 +75,8 @@ shared_ptr POP3Command::AUTH(const string& mechName) // static -shared_ptr POP3Command::AUTH(const string& mechName, const string& initialResponse) -{ +shared_ptr POP3Command::AUTH(const string& mechName, const string& initialResponse) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTH " << mechName << " " << initialResponse; @@ -85,15 +86,15 @@ shared_ptr POP3Command::AUTH(const string& mechName, const string& // static -shared_ptr POP3Command::STLS() -{ +shared_ptr POP3Command::STLS() { + return createCommand("STLS"); } // static -shared_ptr POP3Command::APOP(const string& username, const string& digest) -{ +shared_ptr POP3Command::APOP(const string& username, const string& digest) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "APOP " << username << " " << digest; @@ -103,8 +104,8 @@ shared_ptr POP3Command::APOP(const string& username, const string& // static -shared_ptr POP3Command::USER(const string& username) -{ +shared_ptr POP3Command::USER(const string& username) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "USER " << username; @@ -118,8 +119,8 @@ shared_ptr POP3Command::USER(const string& username) // static -shared_ptr POP3Command::PASS(const string& password) -{ +shared_ptr POP3Command::PASS(const string& password) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "PASS " << password; @@ -133,22 +134,22 @@ shared_ptr POP3Command::PASS(const string& password) // static -shared_ptr POP3Command::STAT() -{ +shared_ptr POP3Command::STAT() { + return createCommand("STAT"); } // static -shared_ptr POP3Command::LIST() -{ +shared_ptr POP3Command::LIST() { + return createCommand("LIST"); } // static -shared_ptr POP3Command::LIST(const unsigned long msg) -{ +shared_ptr POP3Command::LIST(const unsigned long msg) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "LIST " << msg; @@ -158,15 +159,15 @@ shared_ptr POP3Command::LIST(const unsigned long msg) // static -shared_ptr POP3Command::UIDL() -{ +shared_ptr POP3Command::UIDL() { + return createCommand("UIDL"); } // static -shared_ptr POP3Command::UIDL(const unsigned long msg) -{ +shared_ptr POP3Command::UIDL(const unsigned long msg) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "UIDL " << msg; @@ -176,8 +177,8 @@ shared_ptr POP3Command::UIDL(const unsigned long msg) // static -shared_ptr POP3Command::DELE(const unsigned long msg) -{ +shared_ptr POP3Command::DELE(const unsigned long msg) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "DELE " << msg; @@ -187,8 +188,8 @@ shared_ptr POP3Command::DELE(const unsigned long msg) // static -shared_ptr POP3Command::RETR(const unsigned long msg) -{ +shared_ptr POP3Command::RETR(const unsigned long msg) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "RETR " << msg; @@ -198,8 +199,8 @@ shared_ptr POP3Command::RETR(const unsigned long msg) // static -shared_ptr POP3Command::TOP(const unsigned long msg, const unsigned long lines) -{ +shared_ptr POP3Command::TOP(const unsigned long msg, const unsigned long lines) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "TOP " << msg << " " << lines; @@ -209,48 +210,52 @@ shared_ptr POP3Command::TOP(const unsigned long msg, const unsigne // static -shared_ptr POP3Command::RSET() -{ +shared_ptr POP3Command::RSET() { + return createCommand("RSET"); } // static -shared_ptr POP3Command::QUIT() -{ +shared_ptr POP3Command::QUIT() { + return createCommand("QUIT"); } // static -shared_ptr POP3Command::createCommand - (const string& text, const string& traceText) -{ - if (traceText.empty()) +shared_ptr POP3Command::createCommand( + const string& text, + const string& traceText +) { + + if (traceText.empty()) { return shared_ptr (new POP3Command(text, text)); - else + } else { return shared_ptr (new POP3Command(text, traceText)); + } } -const string POP3Command::getText() const -{ +const string POP3Command::getText() const { + return m_text; } -const string POP3Command::getTraceText() const -{ +const string POP3Command::getTraceText() const { + return m_traceText; } -void POP3Command::send(const shared_ptr & conn) -{ +void POP3Command::send(const shared_ptr & conn) { + conn->getSocket()->send(m_text + "\r\n"); - if (conn->getTracer()) + if (conn->getTracer()) { conn->getTracer()->traceSend(m_traceText); + } } diff --git a/src/vmime/net/pop3/POP3Command.hpp b/src/vmime/net/pop3/POP3Command.hpp index 7718ccb2..06a61b9b 100644 --- a/src/vmime/net/pop3/POP3Command.hpp +++ b/src/vmime/net/pop3/POP3Command.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -50,8 +50,8 @@ class POP3Connection; /** A POP3 command that will be sent to the server. */ -class VMIME_EXPORT POP3Command : public object -{ +class VMIME_EXPORT POP3Command : public object { + public: static shared_ptr CAPA(); diff --git a/src/vmime/net/pop3/POP3Connection.cpp b/src/vmime/net/pop3/POP3Connection.cpp index ed098656..749f7ef1 100644 --- a/src/vmime/net/pop3/POP3Connection.cpp +++ b/src/vmime/net/pop3/POP3Connection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -63,37 +63,48 @@ namespace pop3 { -POP3Connection::POP3Connection(const shared_ptr & store, const shared_ptr & auth) - : m_store(store), m_auth(auth), m_socket(null), m_timeoutHandler(null), - m_authenticated(false), m_secured(false), m_capabilitiesFetched(false) -{ +POP3Connection::POP3Connection( + const shared_ptr & store, + const shared_ptr & auth +) + : m_store(store), + m_auth(auth), + m_socket(null), + m_timeoutHandler(null), + m_authenticated(false), + m_secured(false), + m_capabilitiesFetched(false) { + static int connectionId = 0; - if (store->getTracerFactory()) + if (store->getTracerFactory()) { m_tracer = store->getTracerFactory()->create(store, ++connectionId); + } } -POP3Connection::~POP3Connection() -{ - try - { - if (isConnected()) +POP3Connection::~POP3Connection() { + + try { + + if (isConnected()) { disconnect(); - else if (m_socket) + } else if (m_socket) { internalDisconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void POP3Connection::connect() -{ - if (isConnected()) +void POP3Connection::connect() { + + if (isConnected()) { throw exceptions::already_connected(); + } const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS); const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT); @@ -101,16 +112,17 @@ void POP3Connection::connect() shared_ptr store = m_store.lock(); // Create the time-out handler - if (store->getTimeoutHandlerFactory()) + if (store->getTimeoutHandlerFactory()) { m_timeoutHandler = store->getTimeoutHandlerFactory()->create(); + } // Create and connect the socket m_socket = store->getSocketFactory()->create(m_timeoutHandler); m_socket->setTracer(m_tracer); #if VMIME_HAVE_TLS_SUPPORT - if (store->isPOP3S()) // dedicated port/POP3S - { + if (store->isPOP3S()) { // dedicated port/POP3S + shared_ptr tlsSession = tls::TLSSession::create (store->getCertificateVerifier(), store->getSession()->getTLSProperties()); @@ -122,8 +134,7 @@ void POP3Connection::connect() m_secured = true; m_cntInfos = make_shared (address, port, tlsSession, tlsSocket); - } - else + } else #endif // VMIME_HAVE_TLS_SUPPORT { m_cntInfos = make_shared (address, port); @@ -136,11 +147,12 @@ void POP3Connection::connect() // eg: C: // --- S: +OK MailSite POP3 Server 5.3.4.0 Ready <36938848.1056800841.634@somewhere.com> - shared_ptr response = POP3Response::readResponse - (dynamicCast (shared_from_this())); + shared_ptr response = POP3Response::readResponse( + dynamicCast (shared_from_this()) + ); + + if (!response->isSuccess()) { - if (!response->isSuccess()) - { internalDisconnect(); throw exceptions::connection_greeting_error(response->getFirstLine()); } @@ -152,27 +164,23 @@ void POP3Connection::connect() const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED) && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED); - if (!store->isPOP3S() && tls) // only if not POP3S - { - try - { + if (!store->isPOP3S() && tls) { // only if not POP3S + + try { + startTLS(); - } + // Non-fatal error - catch (exceptions::command_error&) - { - if (tlsRequired) - { + } catch (exceptions::command_error&) { + + if (tlsRequired) { throw; - } - else - { + } else { // TLS is not required, so don't bother } - } + // Fatal error - catch (...) - { + } catch (...) { throw; } } @@ -183,28 +191,29 @@ void POP3Connection::connect() } -void POP3Connection::disconnect() -{ - if (!isConnected()) +void POP3Connection::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } internalDisconnect(); } -void POP3Connection::internalDisconnect() -{ - if (m_socket) - { - if (m_socket->isConnected()) - { - try - { +void POP3Connection::internalDisconnect() { + + if (m_socket) { + + if (m_socket->isConnected()) { + + try { + POP3Command::QUIT()->send(dynamicCast (shared_from_this())); POP3Response::readResponse(dynamicCast (shared_from_this())); - } - catch (exception&) - { + + } catch (exception&) { + // Not important } @@ -223,36 +232,36 @@ void POP3Connection::internalDisconnect() } -void POP3Connection::authenticate(const messageId& randomMID) -{ +void POP3Connection::authenticate(const messageId& randomMID) { + getAuthenticator()->setService(m_store.lock()); #if VMIME_HAVE_SASL_SUPPORT // First, try SASL authentication - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) - { - try - { + if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) { + + try { + authenticateSASL(); m_authenticated = true; return; - } - catch (exceptions::authentication_error&) - { - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK)) - { + + } catch (exceptions::authentication_error&) { + + if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL_FALLBACK)) { + // Can't fallback on APOP/normal authentication internalDisconnect(); throw; - } - else - { + + } else { + // Ignore, will try APOP/normal authentication } - } - catch (exception&) - { + + } catch (exception&) { + internalDisconnect(); throw; } @@ -270,11 +279,11 @@ void POP3Connection::authenticate(const messageId& randomMID) shared_ptr conn = dynamicCast (shared_from_this()); shared_ptr response; - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP)) - { + if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP)) { + if (randomMID.getLeft().length() != 0 && - randomMID.getRight().length() != 0) - { + randomMID.getRight().length() != 0) { + // is the result of MD5 applied to "password" shared_ptr md5 = security::digest::messageDigestFactory::getInstance()->create("md5"); @@ -285,13 +294,13 @@ void POP3Connection::authenticate(const messageId& randomMID) POP3Command::APOP(username, md5->getHexDigest())->send(conn); response = POP3Response::readResponse(conn); - if (response->isSuccess()) - { + if (response->isSuccess()) { + m_authenticated = true; return; - } - else - { + + } else { + // Some servers close the connection after an unsuccessful APOP // command, so the fallback may not always work... // @@ -301,31 +310,31 @@ void POP3Connection::authenticate(const messageId& randomMID) // S: +OK Pop server at xxx signing off. // [Connection closed by foreign host.] - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) - { + if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) { + // Can't fallback on basic authentication internalDisconnect(); throw exceptions::authentication_error(response->getFirstLine()); } // Ensure connection is valid (cf. note above) - try - { + try { + POP3Command::NOOP()->send(conn); POP3Response::readResponse(conn); - } - catch (exceptions::socket_exception&) - { + + } catch (exceptions::socket_exception&) { + internalDisconnect(); throw exceptions::authentication_error(response->getFirstLine()); } } - } - else - { + + } else { + // APOP not supported - if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) - { + if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK)) { + // Can't fallback on basic authentication internalDisconnect(); throw exceptions::authentication_error("APOP not supported"); @@ -343,8 +352,8 @@ void POP3Connection::authenticate(const messageId& randomMID) POP3Command::USER(username)->send(conn); response = POP3Response::readResponse(conn); - if (!response->isSuccess()) - { + if (!response->isSuccess()) { + internalDisconnect(); throw exceptions::authentication_error(response->getFirstLine()); } @@ -352,8 +361,8 @@ void POP3Connection::authenticate(const messageId& randomMID) POP3Command::PASS(password)->send(conn); response = POP3Response::readResponse(conn); - if (!response->isSuccess()) - { + if (!response->isSuccess()) { + internalDisconnect(); throw exceptions::authentication_error(response->getFirstLine()); } @@ -364,16 +373,17 @@ void POP3Connection::authenticate(const messageId& randomMID) #if VMIME_HAVE_SASL_SUPPORT -void POP3Connection::authenticateSASL() -{ - if (!dynamicCast (getAuthenticator())) +void POP3Connection::authenticateSASL() { + + if (!dynamicCast (getAuthenticator())) { throw exceptions::authentication_error("No SASL authenticator available."); + } std::vector capa = getCapabilities(); std::vector saslMechs; - for (unsigned int i = 0 ; i < capa.size() ; ++i) - { + for (unsigned int i = 0 ; i < capa.size() ; ++i) { + const string& x = capa[i]; // C: CAPA @@ -391,8 +401,8 @@ void POP3Connection::authenticateSASL() (x[1] == 'A' || x[1] == 'a') && (x[2] == 'S' || x[2] == 's') && (x[3] == 'L' || x[3] == 'l') && - (x[4] == ' ' || x[4] == '\t')) - { + (x[4] == ' ' || x[4] == '\t')) { + const string list(x.begin() + 5, x.end()); std::istringstream iss(list); @@ -400,52 +410,53 @@ void POP3Connection::authenticateSASL() string mech; - while (iss >> mech) + while (iss >> mech) { saslMechs.push_back(mech); + } } } - if (saslMechs.empty()) + if (saslMechs.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } std::vector > mechList; shared_ptr saslContext = security::sasl::SASLContext::create(); - for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) - { - try - { - mechList.push_back - (saslContext->createMechanism(saslMechs[i])); - } - catch (exceptions::no_such_mechanism&) - { + for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) { + + try { + mechList.push_back(saslContext->createMechanism(saslMechs[i])); + } catch (exceptions::no_such_mechanism&) { // Ignore mechanism } } - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try to suggest a mechanism among all those supported shared_ptr suggestedMech = saslContext->suggestMechanism(mechList); - if (!suggestedMech) + if (!suggestedMech) { throw exceptions::authentication_error("Unable to suggest SASL mechanism."); + } // Allow application to choose which mechanisms to use mechList = dynamicCast (getAuthenticator())-> getAcceptableMechanisms(mechList, suggestedMech); - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try each mechanism in the list in turn - for (unsigned int i = 0 ; i < mechList.size() ; ++i) - { + for (unsigned int i = 0 ; i < mechList.size() ; ++i) { + shared_ptr mech = mechList[i]; shared_ptr saslSession = @@ -455,8 +466,8 @@ void POP3Connection::authenticateSASL() shared_ptr authCmd; - if (saslSession->getMechanism()->hasInitialResponse()) - { + if (saslSession->getMechanism()->hasInitialResponse()) { + byte_t* initialResp = 0; size_t initialRespLen = 0; @@ -465,103 +476,108 @@ void POP3Connection::authenticateSASL() string encodedInitialResp(saslContext->encodeB64(initialResp, initialRespLen)); delete [] initialResp; - if (encodedInitialResp.empty()) + if (encodedInitialResp.empty()) { authCmd = POP3Command::AUTH(mech->getName(), "="); - else + } else { authCmd = POP3Command::AUTH(mech->getName(), encodedInitialResp); - } - else - { + } + + } else { + authCmd = POP3Command::AUTH(mech->getName()); } authCmd->send(dynamicCast (shared_from_this())); - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + shared_ptr response = POP3Response::readResponse(dynamicCast (shared_from_this())); - switch (response->getCode()) - { - case POP3Response::CODE_OK: - { - m_socket = saslSession->getSecuredSocket(m_socket); - return; - } - case POP3Response::CODE_READY: - { - byte_t* challenge = 0; - size_t challengeLen = 0; + switch (response->getCode()) { - byte_t* resp = 0; - size_t respLen = 0; + case POP3Response::CODE_OK: { - try - { - // Extract challenge - saslContext->decodeB64(response->getText(), &challenge, &challengeLen); - - // Prepare response - saslSession->evaluateChallenge - (challenge, challengeLen, &resp, &respLen); - - // Send response - const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; - m_socket->sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); - - if (m_tracer) - m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); + m_socket = saslSession->getSecuredSocket(m_socket); + return; } - catch (exceptions::sasl_exception& e) - { - if (challenge) - { - delete [] challenge; - challenge = NULL; + + case POP3Response::CODE_READY: { + + byte_t* challenge = 0; + size_t challengeLen = 0; + + byte_t* resp = 0; + size_t respLen = 0; + + try { + + // Extract challenge + saslContext->decodeB64(response->getText(), &challenge, &challengeLen); + + // Prepare response + saslSession->evaluateChallenge(challenge, challengeLen, &resp, &respLen); + + // Send response + const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; + m_socket->sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); + + if (m_tracer) { + m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); + } + + } catch (exceptions::sasl_exception& e) { + + if (challenge) { + delete [] challenge; + challenge = NULL; + } + + if (resp) { + delete [] resp; + resp = NULL; + } + + // Cancel SASL exchange + m_socket->send("*\r\n"); + + if (m_tracer) { + m_tracer->traceSend("*"); + } + + } catch (...) { + + if (challenge) { + delete [] challenge; + } + + if (resp) { + delete [] resp; + } + + throw; } - if (resp) - { - delete [] resp; - resp = NULL; + if (challenge) { + delete [] challenge; } - // Cancel SASL exchange - m_socket->send("*\r\n"); - - if (m_tracer) - m_tracer->traceSend("*"); - } - catch (...) - { - if (challenge) - delete [] challenge; - - if (resp) + if (resp) { delete [] resp; + } - throw; + break; } - if (challenge) - delete [] challenge; + default: - if (resp) - delete [] resp; - - break; - } - default: - - cont = false; - break; + cont = false; + break; } } } - throw exceptions::authentication_error - ("Could not authenticate using SASL: all mechanisms failed."); + throw exceptions::authentication_error("Could not authenticate using SASL: all mechanisms failed."); } #endif // VMIME_HAVE_SASL_SUPPORT @@ -569,32 +585,34 @@ void POP3Connection::authenticateSASL() #if VMIME_HAVE_TLS_SUPPORT -void POP3Connection::startTLS() -{ - try - { +void POP3Connection::startTLS() { + + try { + POP3Command::STLS()->send(dynamicCast (shared_from_this())); shared_ptr response = POP3Response::readResponse(dynamicCast (shared_from_this())); - if (!response->isSuccess()) + if (!response->isSuccess()) { throw exceptions::command_error("STLS", response->getFirstLine()); + } - shared_ptr tlsSession = tls::TLSSession::create - (m_store.lock()->getCertificateVerifier(), - m_store.lock()->getSession()->getTLSProperties()); + shared_ptr tlsSession = tls::TLSSession::create( + m_store.lock()->getCertificateVerifier(), + m_store.lock()->getSession()->getTLSProperties() + ); - shared_ptr tlsSocket = - tlsSession->getSocket(m_socket); + shared_ptr tlsSocket = tlsSession->getSocket(m_socket); tlsSocket->handshake(); m_socket = tlsSocket; m_secured = true; - m_cntInfos = make_shared - (m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket); + m_cntInfos = make_shared ( + m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket + ); // " Once TLS has been started, the client MUST discard cached // information about server capabilities and SHOULD re-issue @@ -602,14 +620,14 @@ void POP3Connection::startTLS() // man-in-the-middle attacks which alter the capabilities list // prior to STLS. " (RFC-2595) invalidateCapabilities(); - } - catch (exceptions::command_error&) - { + + } catch (exceptions::command_error&) { + // Non-fatal error throw; - } - catch (exception&) - { + + } catch (exception&) { + // Fatal error internalDisconnect(); throw; @@ -619,24 +637,25 @@ void POP3Connection::startTLS() #endif // VMIME_HAVE_TLS_SUPPORT -const std::vector POP3Connection::getCapabilities() -{ - if (!m_capabilitiesFetched) +const std::vector POP3Connection::getCapabilities() { + + if (!m_capabilitiesFetched) { fetchCapabilities(); + } return m_capabilities; } -void POP3Connection::invalidateCapabilities() -{ +void POP3Connection::invalidateCapabilities() { + m_capabilities.clear(); m_capabilitiesFetched = false; } -void POP3Connection::fetchCapabilities() -{ +void POP3Connection::fetchCapabilities() { + POP3Command::CAPA()->send(dynamicCast (shared_from_this())); shared_ptr response = @@ -644,10 +663,11 @@ void POP3Connection::fetchCapabilities() std::vector res; - if (response->isSuccess()) - { - for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) + if (response->isSuccess()) { + + for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) { res.push_back(response->getLineAt(i)); + } } m_capabilities = res; @@ -655,56 +675,56 @@ void POP3Connection::fetchCapabilities() } -bool POP3Connection::isConnected() const -{ +bool POP3Connection::isConnected() const { + return m_socket && m_socket->isConnected() && m_authenticated; } -bool POP3Connection::isSecuredConnection() const -{ +bool POP3Connection::isSecuredConnection() const { + return m_secured; } -shared_ptr POP3Connection::getConnectionInfos() const -{ +shared_ptr POP3Connection::getConnectionInfos() const { + return m_cntInfos; } -shared_ptr POP3Connection::getStore() -{ +shared_ptr POP3Connection::getStore() { + return m_store.lock(); } -shared_ptr POP3Connection::getSession() -{ +shared_ptr POP3Connection::getSession() { + return m_store.lock()->getSession(); } -shared_ptr POP3Connection::getSocket() -{ +shared_ptr POP3Connection::getSocket() { + return m_socket; } -shared_ptr POP3Connection::getTracer() -{ +shared_ptr POP3Connection::getTracer() { + return m_tracer; } -shared_ptr POP3Connection::getTimeoutHandler() -{ +shared_ptr POP3Connection::getTimeoutHandler() { + return m_timeoutHandler; } -shared_ptr POP3Connection::getAuthenticator() -{ +shared_ptr POP3Connection::getAuthenticator() { + return m_auth; } diff --git a/src/vmime/net/pop3/POP3Connection.hpp b/src/vmime/net/pop3/POP3Connection.hpp index 032be5cc..26b3f3c6 100644 --- a/src/vmime/net/pop3/POP3Connection.hpp +++ b/src/vmime/net/pop3/POP3Connection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -61,11 +61,15 @@ class POP3Store; /** Manage connection to a POP3 server. */ -class VMIME_EXPORT POP3Connection : public object, public enable_shared_from_this -{ +class VMIME_EXPORT POP3Connection : public object, public enable_shared_from_this { + public: - POP3Connection(const shared_ptr & store, const shared_ptr & auth); + POP3Connection( + const shared_ptr & store, + const shared_ptr & auth + ); + virtual ~POP3Connection(); diff --git a/src/vmime/net/pop3/POP3Folder.cpp b/src/vmime/net/pop3/POP3Folder.cpp index 8c34676e..4ca494fe 100644 --- a/src/vmime/net/pop3/POP3Folder.cpp +++ b/src/vmime/net/pop3/POP3Folder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,59 +45,67 @@ namespace net { namespace pop3 { -POP3Folder::POP3Folder(const folder::path& path, const shared_ptr & store) - : m_store(store), m_path(path), +POP3Folder::POP3Folder( + const folder::path& path, + const shared_ptr & store +) + : m_store(store), + m_path(path), m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), - m_mode(-1), m_open(false) -{ + m_mode(-1), + m_open(false) { + store->registerFolder(this); } -POP3Folder::~POP3Folder() -{ - try - { +POP3Folder::~POP3Folder() { + + try { + shared_ptr store = m_store.lock(); - if (store) - { - if (m_open) + if (store) { + + if (m_open) { close(false); + } store->unregisterFolder(this); - } - else if (m_open) - { + + } else if (m_open) { + onClose(); } - } - catch (...) - { + + } catch (...) { + // Don't throw in destructor } } -int POP3Folder::getMode() const -{ - if (!isOpen()) - throw exceptions::illegal_state("Folder not open"); +int POP3Folder::getMode() const { - return (m_mode); + if (!isOpen()) { + throw exceptions::illegal_state("Folder not open"); + } + + return m_mode; } -const folderAttributes POP3Folder::getAttributes() -{ +const folderAttributes POP3Folder::getAttributes() { + folderAttributes attribs; - if (m_path.isEmpty()) + if (m_path.isEmpty()) { attribs.setType(folderAttributes::TYPE_CONTAINS_FOLDERS); - else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") + } else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") { attribs.setType(folderAttributes::TYPE_CONTAINS_MESSAGES); - else + } else { throw exceptions::folder_not_found(); + } attribs.setFlags(0); @@ -105,72 +113,78 @@ const folderAttributes POP3Folder::getAttributes() } -const folder::path::component POP3Folder::getName() const -{ - return (m_name); +const folder::path::component POP3Folder::getName() const { + + return m_name; } -const folder::path POP3Folder::getFullPath() const -{ - return (m_path); +const folder::path POP3Folder::getFullPath() const { + + return m_path; } -void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable) -{ +void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - if (m_path.isEmpty()) - { - if (mode != MODE_READ_ONLY && failIfModeIsNotAvailable) + if (m_path.isEmpty()) { + + if (mode != MODE_READ_ONLY && failIfModeIsNotAvailable) { throw exceptions::operation_not_supported(); + } m_open = true; m_mode = mode; m_messageCount = 0; - } - else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") - { + + } else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") { + POP3Command::STAT()->send(store->getConnection()); shared_ptr response = POP3Response::readResponse(store->getConnection()); - if (!response->isSuccess()) + if (!response->isSuccess()) { throw exceptions::command_error("STAT", response->getFirstLine()); + } std::istringstream iss(response->getText()); iss.imbue(std::locale::classic()); iss >> m_messageCount; - if (iss.fail()) + if (iss.fail()) { throw exceptions::invalid_response("STAT", response->getFirstLine()); + } m_open = true; m_mode = mode; - } - else - { + + } else { + throw exceptions::folder_not_found(); } } -void POP3Folder::close(const bool expunge) -{ + +void POP3Folder::close(const bool expunge) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - if (!isOpen()) + if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (!expunge) - { + if (!expunge) { POP3Command::RSET()->send(store->getConnection()); POP3Response::readResponse(store->getConnection()); } @@ -182,168 +196,185 @@ void POP3Folder::close(const bool expunge) } -void POP3Folder::onClose() -{ - for (MessageMap::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) +void POP3Folder::onClose() { + + for (MessageMap::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { (*it).first->onFolderClosed(); + } m_messages.clear(); } -void POP3Folder::create(const folderAttributes& /* attribs */) -{ +void POP3Folder::create(const folderAttributes& /* attribs */) { + throw exceptions::operation_not_supported(); } -void POP3Folder::destroy() -{ +void POP3Folder::destroy() { + throw exceptions::operation_not_supported(); } -bool POP3Folder::exists() -{ +bool POP3Folder::exists() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } - return (m_path.isEmpty() || (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX")); + return m_path.isEmpty() || (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX"); } -bool POP3Folder::isOpen() const -{ - return (m_open); +bool POP3Folder::isOpen() const { + + return m_open; } -shared_ptr POP3Folder::getMessage(const size_t num) -{ +shared_ptr POP3Folder::getMessage(const size_t num) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); - else if (num < 1 || num > m_messageCount) + } else if (num < 1 || num > m_messageCount) { throw exceptions::message_not_found(); + } return make_shared (dynamicCast (shared_from_this()), num); } -std::vector > POP3Folder::getMessages(const messageSet& msgs) -{ +std::vector > POP3Folder::getMessages(const messageSet& msgs) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } + + if (msgs.isNumberSet()) { - if (msgs.isNumberSet()) - { const std::vector numbers = POP3Utils::messageSetToNumberList(msgs, m_messageCount); std::vector > messages; shared_ptr thisFolder(dynamicCast (shared_from_this())); - for (std::vector ::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it) - { - if (*it < 1|| *it > m_messageCount) + for (std::vector ::const_iterator it = numbers.begin() ; it != numbers.end() ; ++it) { + + if (*it < 1|| *it > m_messageCount) { throw exceptions::message_not_found(); + } messages.push_back(make_shared (thisFolder, *it)); } return messages; - } - else - { + + } else { + throw exceptions::operation_not_supported(); } } -size_t POP3Folder::getMessageCount() -{ +size_t POP3Folder::getMessageCount() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - return (m_messageCount); + return m_messageCount; } -shared_ptr POP3Folder::getFolder(const folder::path::component& name) -{ +shared_ptr POP3Folder::getFolder(const folder::path::component& name) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } return shared_ptr (new POP3Folder(m_path / name, store)); } -std::vector > POP3Folder::getFolders(const bool /* recursive */) -{ +std::vector > POP3Folder::getFolders(const bool /* recursive */) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } + + if (m_path.isEmpty()) { - if (m_path.isEmpty()) - { std::vector > v; v.push_back(shared_ptr (new POP3Folder(folder::path::component("INBOX"), store))); - return (v); - } - else - { + return v; + + } else { + std::vector > v; - return (v); + return v; } } -void POP3Folder::fetchMessages(std::vector >& msg, const fetchAttributes& options, - utility::progressListener* progress) -{ +void POP3Folder::fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress +) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - if (msg.empty()) + if (msg.empty()) { return; + } const size_t total = msg.size(); size_t current = 0; - if (progress) + if (progress) { progress->start(total); - - for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { - dynamicCast (*it)->fetch - (dynamicCast (shared_from_this()), options); - - if (progress) - progress->progress(++current, total); } - if (options.has(fetchAttributes::SIZE)) - { + for (std::vector >::iterator it = msg.begin() ; + it != msg.end() ; ++it) { + + dynamicCast (*it)->fetch( + dynamicCast (shared_from_this()), + options + ); + + if (progress) { + progress->progress(++current, total); + } + } + + if (options.has(fetchAttributes::SIZE)) { + // Send the "LIST" command POP3Command::LIST()->send(store->getConnection()); @@ -351,8 +382,8 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f shared_ptr response = POP3Response::readMultilineResponse(store->getConnection()); - if (response->isSuccess()) - { + if (response->isSuccess()) { + // C: LIST // S: +OK // S: 1 47548 @@ -362,14 +393,14 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f POP3Utils::parseMultiListOrUidlResponse(response, result); for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { + it != msg.end() ; ++it) { + shared_ptr m = dynamicCast (*it); std::map ::const_iterator x = result.find(m->m_num); - if (x != result.end()) - { + if (x != result.end()) { + size_t size = 0; std::istringstream iss((*x).second); @@ -380,11 +411,10 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f } } } - } - if (options.has(fetchAttributes::UID)) - { + if (options.has(fetchAttributes::UID)) { + // Send the "UIDL" command POP3Command::UIDL()->send(store->getConnection()); @@ -392,8 +422,8 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f shared_ptr response = POP3Response::readMultilineResponse(store->getConnection()); - if (response->isSuccess()) - { + if (response->isSuccess()) { + // C: UIDL // S: +OK // S: 1 whqtswO00WBw418f9t5JxYwZ @@ -403,37 +433,42 @@ void POP3Folder::fetchMessages(std::vector >& msg, const f POP3Utils::parseMultiListOrUidlResponse(response, result); for (std::vector >::iterator it = msg.begin() ; - it != msg.end() ; ++it) - { + it != msg.end() ; ++it) { + shared_ptr m = dynamicCast (*it); std::map ::const_iterator x = result.find(m->m_num); - if (x != result.end()) + if (x != result.end()) { m->m_uid = (*x).second; + } } } } - if (progress) + if (progress) { progress->stop(total); + } } -void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) -{ +void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttributes& options) { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } - dynamicCast (msg)->fetch - (dynamicCast (shared_from_this()), options); + dynamicCast (msg)->fetch( + dynamicCast (shared_from_this()), + options + ); + + if (options.has(fetchAttributes::SIZE)) { - if (options.has(fetchAttributes::SIZE)) - { // Send the "LIST" command POP3Command::LIST(msg->getNumber())->send(store->getConnection()); @@ -441,8 +476,8 @@ void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttrib shared_ptr response = POP3Response::readResponse(store->getConnection()); - if (response->isSuccess()) - { + if (response->isSuccess()) { + string responseText = response->getText(); // C: LIST 2 @@ -453,8 +488,8 @@ void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttrib while (it != responseText.end() && !(*it == ' ' || *it == '\t')) ++it; while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it; - if (it != responseText.end()) - { + if (it != responseText.end()) { + size_t size = 0; std::istringstream iss(string(it, responseText.end())); @@ -466,8 +501,8 @@ void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttrib } } - if (options.has(fetchAttributes::UID)) - { + if (options.has(fetchAttributes::UID)) { + // Send the "UIDL" command POP3Command::UIDL(msg->getNumber())->send(store->getConnection()); @@ -475,8 +510,8 @@ void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttrib shared_ptr response = POP3Response::readResponse(store->getConnection()); - if (response->isSuccess()) - { + if (response->isSuccess()) { + string responseText = response->getText(); // C: UIDL 2 @@ -487,21 +522,22 @@ void POP3Folder::fetchMessage(const shared_ptr & msg, const fetchAttrib while (it != responseText.end() && !(*it == ' ' || *it == '\t')) ++it; while (it != responseText.end() && (*it == ' ' || *it == '\t')) ++it; - if (it != responseText.end()) - { - dynamicCast (msg)->m_uid = - string(it, responseText.end()); + if (it != responseText.end()) { + dynamicCast (msg)->m_uid = string(it, responseText.end()); } } } } -std::vector > POP3Folder::getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs) -{ - if (msgs.isEmpty()) +std::vector > POP3Folder::getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs +) { + + if (msgs.isEmpty()) { return std::vector >(); + } std::vector > messages = getMessages(msgs); fetchMessages(messages, attribs); @@ -510,77 +546,84 @@ std::vector > POP3Folder::getAndFetchMessages } -int POP3Folder::getFetchCapabilities() const -{ - return fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | - fetchAttributes::SIZE | fetchAttributes::FULL_HEADER | - fetchAttributes::UID | fetchAttributes::IMPORTANCE; +int POP3Folder::getFetchCapabilities() const { + + return fetchAttributes::ENVELOPE | + fetchAttributes::CONTENT_INFO | + fetchAttributes::SIZE | + fetchAttributes::FULL_HEADER | + fetchAttributes::UID | + fetchAttributes::IMPORTANCE; } -shared_ptr POP3Folder::getParent() -{ - if (m_path.isEmpty()) +shared_ptr POP3Folder::getParent() { + + if (m_path.isEmpty()) { return null; - else + } else { return shared_ptr (new POP3Folder(m_path.getParent(), m_store.lock())); + } } -shared_ptr POP3Folder::getStore() const -{ +shared_ptr POP3Folder::getStore() const { + return m_store.lock(); } -shared_ptr POP3Folder::getStore() -{ +shared_ptr POP3Folder::getStore() { + return m_store.lock(); } -void POP3Folder::registerMessage(POP3Message* msg) -{ +void POP3Folder::registerMessage(POP3Message* msg) { + m_messages.insert(MessageMap::value_type(msg, msg->getNumber())); } -void POP3Folder::unregisterMessage(POP3Message* msg) -{ +void POP3Folder::unregisterMessage(POP3Message* msg) { + m_messages.erase(msg); } -void POP3Folder::onStoreDisconnected() -{ +void POP3Folder::onStoreDisconnected() { + m_store.reset(); } -void POP3Folder::deleteMessages(const messageSet& msgs) -{ +void POP3Folder::deleteMessages(const messageSet& msgs) { + shared_ptr store = m_store.lock(); const std::vector nums = POP3Utils::messageSetToNumberList(msgs, m_messageCount); - if (nums.empty()) + if (nums.empty()) { throw exceptions::invalid_argument(); + } - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); - else if (!isOpen()) + } else if (!isOpen()) { throw exceptions::illegal_state("Folder not open"); + } for (std::vector ::const_iterator - it = nums.begin() ; it != nums.end() ; ++it) - { + it = nums.begin() ; it != nums.end() ; ++it) { + POP3Command::DELE(*it)->send(store->getConnection()); shared_ptr response = POP3Response::readResponse(store->getConnection()); - if (!response->isSuccess()) + if (!response->isSuccess()) { throw exceptions::command_error("DELE", response->getFirstLine()); + } } // Sort message list @@ -593,62 +636,77 @@ void POP3Folder::deleteMessages(const messageSet& msgs) // Update local flags for (std::map ::iterator it = - m_messages.begin() ; it != m_messages.end() ; ++it) - { + m_messages.begin() ; it != m_messages.end() ; ++it) { + POP3Message* msg = (*it).first; - if (std::binary_search(list.begin(), list.end(), msg->getNumber())) + if (std::binary_search(list.begin(), list.end(), msg->getNumber())) { msg->m_deleted = true; + } } // Notify message flags changed shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageChangedEvent::TYPE_FLAGS, list); + make_shared ( + dynamicCast (shared_from_this()), + events::messageChangedEvent::TYPE_FLAGS, + list + ); notifyMessageChanged(event); } -void POP3Folder::setMessageFlags(const messageSet& /* msgs */, - const int /* flags */, const int /* mode */) -{ +void POP3Folder::setMessageFlags( + const messageSet& /* msgs */, + const int /* flags */, + const int /* mode */ +) { + throw exceptions::operation_not_supported(); } -void POP3Folder::rename(const folder::path& /* newPath */) -{ +void POP3Folder::rename(const folder::path& /* newPath */) { + throw exceptions::operation_not_supported(); } -messageSet POP3Folder::addMessage - (const shared_ptr & /* msg */, const int /* flags */, - vmime::datetime* /* date */, utility::progressListener* /* progress */) -{ +messageSet POP3Folder::addMessage( + const shared_ptr & /* msg */, + const int /* flags */, + vmime::datetime* /* date */, + utility::progressListener* /* progress */ +) { + throw exceptions::operation_not_supported(); } -messageSet POP3Folder::addMessage - (utility::inputStream& /* is */, const size_t /* size */, const int /* flags */, - vmime::datetime* /* date */, utility::progressListener* /* progress */) -{ +messageSet POP3Folder::addMessage( + utility::inputStream& /* is */, + const size_t /* size */, + const int /* flags */, + vmime::datetime* /* date */, + utility::progressListener* /* progress */ +) { + throw exceptions::operation_not_supported(); } -messageSet POP3Folder::copyMessages - (const folder::path& /* dest */, const messageSet& /* msgs */) -{ +messageSet POP3Folder::copyMessages( + const folder::path& /* dest */, + const messageSet& /* msgs */ +) { + throw exceptions::operation_not_supported(); } -void POP3Folder::status(size_t& count, size_t& unseen) -{ +void POP3Folder::status(size_t& count, size_t& unseen) { + count = 0; unseen = 0; @@ -661,20 +719,22 @@ void POP3Folder::status(size_t& count, size_t& unseen) } -shared_ptr POP3Folder::getStatus() -{ +shared_ptr POP3Folder::getStatus() { + shared_ptr store = m_store.lock(); - if (!store) + if (!store) { throw exceptions::illegal_state("Store disconnected"); + } POP3Command::STAT()->send(store->getConnection()); shared_ptr response = POP3Response::readResponse(store->getConnection()); - if (!response->isSuccess()) + if (!response->isSuccess()) { throw exceptions::command_error("STAT", response->getFirstLine()); + } size_t count = 0; @@ -689,40 +749,45 @@ shared_ptr POP3Folder::getStatus() status->setUnseenCount(count); // Update local message count - if (m_messageCount != count) - { + if (m_messageCount != count) { + const size_t oldCount = m_messageCount; m_messageCount = count; - if (count > oldCount) - { + if (count > oldCount) { + std::vector nums; nums.resize(count - oldCount); - for (size_t i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) + for (size_t i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) { nums[j] = i; + } // Notify message count changed shared_ptr event = - make_shared - (dynamicCast (shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast (shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); notifyMessageCount(event); // Notify folders with the same path for (std::list ::iterator it = store->m_folders.begin() ; - it != store->m_folders.end() ; ++it) - { - if ((*it) != this && (*it)->getFullPath() == m_path) - { + it != store->m_folders.end() ; ++it) { + + if ((*it) != this && (*it)->getFullPath() == m_path) { + (*it)->m_messageCount = count; shared_ptr event = - make_shared - (dynamicCast ((*it)->shared_from_this()), - events::messageCountEvent::TYPE_ADDED, nums); + make_shared ( + dynamicCast ((*it)->shared_from_this()), + events::messageCountEvent::TYPE_ADDED, + nums + ); (*it)->notifyMessageCount(event); } @@ -734,15 +799,15 @@ shared_ptr POP3Folder::getStatus() } -void POP3Folder::expunge() -{ +void POP3Folder::expunge() { + // Not supported by POP3 protocol (deleted messages are automatically // expunged at the end of the session...). } -std::vector POP3Folder::getMessageNumbersStartingOnUID(const message::uid& /* uid */) -{ +std::vector POP3Folder::getMessageNumbersStartingOnUID(const message::uid& /* uid */) { + throw exceptions::operation_not_supported(); } diff --git a/src/vmime/net/pop3/POP3Folder.hpp b/src/vmime/net/pop3/POP3Folder.hpp index 92be088b..73e29f99 100644 --- a/src/vmime/net/pop3/POP3Folder.hpp +++ b/src/vmime/net/pop3/POP3Folder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -50,9 +50,8 @@ class POP3Message; /** POP3 folder implementation. */ +class VMIME_EXPORT POP3Folder : public folder { -class VMIME_EXPORT POP3Folder : public folder -{ private: friend class POP3Store; @@ -94,10 +93,26 @@ public: void deleteMessages(const messageSet& msgs); - void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + void setMessageFlags( + const messageSet& msgs, + const int flags, + const int mode = message::FLAG_MODE_SET + ); - messageSet addMessage(const shared_ptr & msg, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); - messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = -1, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + messageSet addMessage( + const shared_ptr & msg, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); + + messageSet addMessage( + utility::inputStream& is, + const size_t size, + const int flags = -1, + vmime::datetime* date = NULL, + utility::progressListener* progress = NULL + ); messageSet copyMessages(const folder::path& dest, const messageSet& msgs); @@ -112,11 +127,18 @@ public: shared_ptr getStore(); - void fetchMessages(std::vector >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessages( + std::vector >& msg, + const fetchAttributes& options, + utility::progressListener* progress = NULL + ); + void fetchMessage(const shared_ptr & msg, const fetchAttributes& options); - std::vector > getAndFetchMessages - (const messageSet& msgs, const fetchAttributes& attribs); + std::vector > getAndFetchMessages( + const messageSet& msgs, + const fetchAttributes& attribs + ); int getFetchCapabilities() const; diff --git a/src/vmime/net/pop3/POP3FolderStatus.cpp b/src/vmime/net/pop3/POP3FolderStatus.cpp index 15e4cc92..9f2c49fb 100644 --- a/src/vmime/net/pop3/POP3FolderStatus.cpp +++ b/src/vmime/net/pop3/POP3FolderStatus.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,45 +37,45 @@ namespace pop3 { POP3FolderStatus::POP3FolderStatus() : m_count(0), - m_unseen(0) -{ + m_unseen(0) { + } POP3FolderStatus::POP3FolderStatus(const POP3FolderStatus& other) : folderStatus(), m_count(other.m_count), - m_unseen(other.m_unseen) -{ + m_unseen(other.m_unseen) { + } -size_t POP3FolderStatus::getMessageCount() const -{ +size_t POP3FolderStatus::getMessageCount() const { + return m_count; } -size_t POP3FolderStatus::getUnseenCount() const -{ +size_t POP3FolderStatus::getUnseenCount() const { + return m_unseen; } -void POP3FolderStatus::setMessageCount(const size_t count) -{ +void POP3FolderStatus::setMessageCount(const size_t count) { + m_count = count; } -void POP3FolderStatus::setUnseenCount(const size_t unseen) -{ +void POP3FolderStatus::setUnseenCount(const size_t unseen) { + m_unseen = unseen; } -shared_ptr POP3FolderStatus::clone() const -{ +shared_ptr POP3FolderStatus::clone() const { + return make_shared (*this); } diff --git a/src/vmime/net/pop3/POP3FolderStatus.hpp b/src/vmime/net/pop3/POP3FolderStatus.hpp index 74c07a51..0ce413e4 100644 --- a/src/vmime/net/pop3/POP3FolderStatus.hpp +++ b/src/vmime/net/pop3/POP3FolderStatus.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,9 +41,8 @@ namespace pop3 { /** Holds the status of a POP3 folder. */ +class VMIME_EXPORT POP3FolderStatus : public folderStatus { -class VMIME_EXPORT POP3FolderStatus : public folderStatus -{ public: POP3FolderStatus(); diff --git a/src/vmime/net/pop3/POP3Message.cpp b/src/vmime/net/pop3/POP3Message.cpp index 913219b3..8d6b7f53 100644 --- a/src/vmime/net/pop3/POP3Message.cpp +++ b/src/vmime/net/pop3/POP3Message.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,162 +44,186 @@ namespace net { namespace pop3 { -POP3Message::POP3Message(const shared_ptr & folder, const size_t num) - : m_folder(folder), m_num(num), m_size(-1), m_deleted(false) -{ +POP3Message::POP3Message( + const shared_ptr & folder, + const size_t num +) + : m_folder(folder), + m_num(num), + m_size(-1), + m_deleted(false) { + folder->registerMessage(this); } -POP3Message::~POP3Message() -{ - try - { +POP3Message::~POP3Message() { + + try { + shared_ptr folder = m_folder.lock(); - if (folder) + if (folder) { folder->unregisterMessage(this); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void POP3Message::onFolderClosed() -{ +void POP3Message::onFolderClosed() { + m_folder.reset(); } -size_t POP3Message::getNumber() const -{ - return (m_num); +size_t POP3Message::getNumber() const { + + return m_num; } -const message::uid POP3Message::getUID() const -{ - return (m_uid); +const message::uid POP3Message::getUID() const { + + return m_uid; } -size_t POP3Message::getSize() const -{ - if (m_size == static_cast (-1)) +size_t POP3Message::getSize() const { + + if (m_size == static_cast (-1)) { throw exceptions::unfetched_object(); + } - return (m_size); + return m_size; } -bool POP3Message::isExpunged() const -{ - return (false); +bool POP3Message::isExpunged() const { + + return false; } -int POP3Message::getFlags() const -{ +int POP3Message::getFlags() const { + int flags = 0; - if (m_deleted) + if (m_deleted) { flags |= FLAG_DELETED; + } - return (flags); + return flags; } -shared_ptr POP3Message::getStructure() const -{ +shared_ptr POP3Message::getStructure() const { + throw exceptions::operation_not_supported(); } -shared_ptr POP3Message::getStructure() -{ +shared_ptr POP3Message::getStructure() { + throw exceptions::operation_not_supported(); } -shared_ptr POP3Message::getHeader() const -{ - if (m_header == NULL) +shared_ptr POP3Message::getHeader() const { + + if (!m_header) { throw exceptions::unfetched_object(); + } - return (m_header); + return m_header; } -void POP3Message::extract - (utility::outputStream& os, - utility::progressListener* progress, - const size_t start, const size_t length, - const bool /* peek */) const -{ +void POP3Message::extract( + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, + const size_t length, + const bool /* peek */ +) const { + shared_ptr folder = m_folder.lock(); - if (!folder) + if (!folder) { throw exceptions::illegal_state("Folder closed"); - else if (!folder->getStore()) + } else if (!folder->getStore()) { throw exceptions::illegal_state("Store disconnected"); + } - if (start != 0 && length != static_cast (-1)) + if (start != 0 && length != static_cast (-1)) { throw exceptions::partial_fetch_not_supported(); + } // Emit the "RETR" command shared_ptr store = folder->m_store.lock(); POP3Command::RETR(m_num)->send(store->getConnection()); - try - { - POP3Response::readLargeResponse - (store->getConnection(), os, progress, m_size == static_cast (-1) ? 0 : m_size); - } - catch (exceptions::command_error& e) - { + try { + + POP3Response::readLargeResponse( + store->getConnection(), os, progress, + m_size == static_cast (-1) ? 0 : m_size + ); + + } catch (exceptions::command_error& e) { + throw exceptions::command_error("RETR", e.response()); } } -void POP3Message::extractPart - (const shared_ptr & /* p */, - utility::outputStream& /* os */, - utility::progressListener* /* progress */, - const size_t /* start */, const size_t /* length */, - const bool /* peek */) const -{ +void POP3Message::extractPart( + const shared_ptr & /* p */, + utility::outputStream& /* os */, + utility::progressListener* /* progress */, + const size_t /* start */, + const size_t /* length */, + const bool /* peek */ +) const { + throw exceptions::operation_not_supported(); } -void POP3Message::fetchPartHeader(const shared_ptr & /* p */) -{ +void POP3Message::fetchPartHeader(const shared_ptr & /* p */) { + throw exceptions::operation_not_supported(); } -void POP3Message::fetch(const shared_ptr & msgFolder, const fetchAttributes& options) -{ +void POP3Message::fetch( + const shared_ptr & msgFolder, + const fetchAttributes& options +) { + shared_ptr folder = m_folder.lock(); - if (folder != msgFolder) + if (folder != msgFolder) { throw exceptions::folder_not_found(); + } // STRUCTURE and FLAGS attributes are not supported by POP3 - if (options.has(fetchAttributes::STRUCTURE | fetchAttributes::FLAGS)) + if (options.has(fetchAttributes::STRUCTURE | fetchAttributes::FLAGS)) { throw exceptions::operation_not_supported(); + } // Check for the real need to fetch the full header static const int optionsRequiringHeader = fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO | fetchAttributes::FULL_HEADER | fetchAttributes::IMPORTANCE; - if (!options.has(optionsRequiringHeader)) + if (!options.has(optionsRequiringHeader)) { return; + } // No need to differenciate between ENVELOPE, CONTENT_INFO, ... // since POP3 only permits to retrieve the whole header and not @@ -210,32 +234,34 @@ void POP3Message::fetch(const shared_ptr & msgFolder, const fetchAtt POP3Command::TOP(m_num, 0)->send(store->getConnection()); - try - { + try { + string buffer; utility::outputStreamStringAdapter bufferStream(buffer); - POP3Response::readLargeResponse(store->getConnection(), - bufferStream, /* progress */ NULL, /* predictedSize */ 0); + POP3Response::readLargeResponse( + store->getConnection(), + bufferStream, /* progress */ NULL, /* predictedSize */ 0 + ); m_header = make_shared
(); m_header->parse(buffer); - } - catch (exceptions::command_error& e) - { + + } catch (exceptions::command_error& e) { + throw exceptions::command_error("TOP", e.response()); } } -void POP3Message::setFlags(const int /* flags */, const int /* mode */) -{ +void POP3Message::setFlags(const int /* flags */, const int /* mode */) { + throw exceptions::operation_not_supported(); } -shared_ptr POP3Message::getParsedMessage() -{ +shared_ptr POP3Message::getParsedMessage() { + std::ostringstream oss; utility::outputStreamAdapter os(oss); diff --git a/src/vmime/net/pop3/POP3Message.hpp b/src/vmime/net/pop3/POP3Message.hpp index 7ac86a1b..3d6dc921 100644 --- a/src/vmime/net/pop3/POP3Message.hpp +++ b/src/vmime/net/pop3/POP3Message.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,9 +45,8 @@ class POP3Folder; /** POP3 message implementation. */ +class VMIME_EXPORT POP3Message : public message { -class VMIME_EXPORT POP3Message : public message -{ private: friend class POP3Folder; @@ -77,18 +76,22 @@ public: int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); - void extract - (utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, const size_t length = -1, - const bool peek = false) const; + void extract( + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; - void extractPart - (const shared_ptr & p, - utility::outputStream& os, - utility::progressListener* progress = NULL, - const size_t start = 0, const size_t length = -1, - const bool peek = false) const; + void extractPart( + const shared_ptr & p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false + ) const; void fetchPartHeader(const shared_ptr & p); diff --git a/src/vmime/net/pop3/POP3Response.cpp b/src/vmime/net/pop3/POP3Response.cpp index 1d510fb3..725841e3 100644 --- a/src/vmime/net/pop3/POP3Response.cpp +++ b/src/vmime/net/pop3/POP3Response.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,17 +46,26 @@ namespace net { namespace pop3 { -POP3Response::POP3Response(const shared_ptr & sok, const shared_ptr & toh, const shared_ptr & tracer) - : m_socket(sok), m_timeoutHandler(toh), m_tracer(tracer) -{ +POP3Response::POP3Response( + const shared_ptr & sok, + const shared_ptr & toh, + const shared_ptr & tracer +) + : m_socket(sok), + m_timeoutHandler(toh), + m_tracer(tracer) { + } // static -shared_ptr POP3Response::readResponse(const shared_ptr & conn) -{ - shared_ptr resp = shared_ptr - (new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())); +shared_ptr POP3Response::readResponse( + const shared_ptr & conn +) { + + shared_ptr resp = shared_ptr ( + new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer()) + ); string buffer; resp->readResponseImpl(buffer, /* multiLine */ false); @@ -65,18 +74,22 @@ shared_ptr POP3Response::readResponse(const shared_ptr m_code = getResponseCode(buffer); stripResponseCode(buffer, resp->m_text); - if (resp->m_tracer) + if (resp->m_tracer) { resp->m_tracer->traceReceive(buffer); + } return resp; } // static -shared_ptr POP3Response::readMultilineResponse(const shared_ptr & conn) -{ - shared_ptr resp = shared_ptr - (new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())); +shared_ptr POP3Response::readMultilineResponse( + const shared_ptr & conn +) { + + shared_ptr resp = shared_ptr ( + new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer()) + ); string buffer; resp->readResponseImpl(buffer, /* multiLine */ true); @@ -91,32 +104,39 @@ shared_ptr POP3Response::readMultilineResponse(const shared_ptr < std::istringstream iss(nextLines); string line; - if (resp->m_tracer) + if (resp->m_tracer) { resp->m_tracer->traceReceive(firstLine); + } + + while (std::getline(iss, line, '\n')) { - while (std::getline(iss, line, '\n')) - { line = utility::stringUtils::trim(line); resp->m_lines.push_back(line); - if (resp->m_tracer) + if (resp->m_tracer) { resp->m_tracer->traceReceive(line); + } } - if (resp->m_tracer) + if (resp->m_tracer) { resp->m_tracer->traceReceive("."); + } return resp; } // static -shared_ptr POP3Response::readLargeResponse - (const shared_ptr & conn, utility::outputStream& os, - utility::progressListener* progress, const size_t predictedSize) -{ - shared_ptr resp = shared_ptr - (new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer())); +shared_ptr POP3Response::readLargeResponse( + const shared_ptr & conn, + utility::outputStream& os, + utility::progressListener* progress, + const size_t predictedSize +) { + + shared_ptr resp = shared_ptr ( + new POP3Response(conn->getSocket(), conn->getTimeoutHandler(), conn->getTracer()) + ); string firstLine; const size_t length = resp->readResponseImpl(firstLine, os, progress, predictedSize); @@ -125,8 +145,7 @@ shared_ptr POP3Response::readLargeResponse resp->m_code = getResponseCode(firstLine); stripResponseCode(firstLine, resp->m_text); - if (resp->m_tracer) - { + if (resp->m_tracer) { resp->m_tracer->traceReceive(firstLine); resp->m_tracer->traceReceiveBytes(length - firstLine.length()); resp->m_tracer->traceReceive("."); @@ -136,60 +155,62 @@ shared_ptr POP3Response::readLargeResponse } -bool POP3Response::isSuccess() const -{ +bool POP3Response::isSuccess() const { + return m_code == CODE_OK; } -const string POP3Response::getFirstLine() const -{ +const string POP3Response::getFirstLine() const { + return m_firstLine; } -POP3Response::ResponseCode POP3Response::getCode() const -{ +POP3Response::ResponseCode POP3Response::getCode() const { + return m_code; } -const string POP3Response::getText() const -{ +const string POP3Response::getText() const { + return m_text; } -const string POP3Response::getLineAt(const size_t pos) const -{ +const string POP3Response::getLineAt(const size_t pos) const { + return m_lines[pos]; } -size_t POP3Response::getLineCount() const -{ +size_t POP3Response::getLineCount() const { + return m_lines.size(); } -void POP3Response::readResponseImpl(string& buffer, const bool multiLine) -{ +void POP3Response::readResponseImpl(string& buffer, const bool multiLine) { + bool foundTerminator = false; - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } buffer.clear(); char last1 = '\0', last2 = '\0'; - for ( ; !foundTerminator ; ) - { + for ( ; !foundTerminator ; ) { + // Check whether the time-out delay is elapsed - if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) + if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { throw exceptions::operation_timed_out(); + } m_timeoutHandler->resetTimeOut(); } @@ -198,36 +219,38 @@ void POP3Response::readResponseImpl(string& buffer, const bool multiLine) string receiveBuffer; m_socket->receive(receiveBuffer); - if (receiveBuffer.empty()) // buffer is empty - { - if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) + if (receiveBuffer.empty()) { // buffer is empty + + if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) { m_socket->waitForWrite(); - else + } else { m_socket->waitForRead(); + } continue; } // We have received data: reset the time-out counter - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } // Check for transparent characters: '\n..' becomes '\n.' const char first = receiveBuffer[0]; - if (first == '.' && last2 == '\n' && last1 == '.') - { + if (first == '.' && last2 == '\n' && last1 == '.') { + receiveBuffer.erase(receiveBuffer.begin()); - } - else if (receiveBuffer.length() >= 2 && first == '.' && - receiveBuffer[1] == '.' && last1 == '\n') - { + + } else if (receiveBuffer.length() >= 2 && first == '.' && + receiveBuffer[1] == '.' && last1 == '\n') { + receiveBuffer.erase(receiveBuffer.begin()); } for (size_t trans ; - string::npos != (trans = receiveBuffer.find("\n..")) ; ) - { + string::npos != (trans = receiveBuffer.find("\n..")) ; ) { + receiveBuffer.replace(trans, 3, "\n."); } @@ -244,28 +267,35 @@ void POP3Response::readResponseImpl(string& buffer, const bool multiLine) // requires a multi-line response, the error response will // include only one line, so we stop waiting for a multi-line // terminator and check for a "normal" one. - if (multiLine && !foundTerminator && buffer.length() >= 4 && buffer[0] == '-') - { + if (multiLine && + !foundTerminator && + buffer.length() >= 4 && buffer[0] == '-') { + foundTerminator = checkTerminator(buffer, false); } } } -size_t POP3Response::readResponseImpl - (string& firstLine, utility::outputStream& os, - utility::progressListener* progress, const size_t predictedSize) -{ +size_t POP3Response::readResponseImpl( + string& firstLine, + utility::outputStream& os, + utility::progressListener* progress, + const size_t predictedSize +) { + size_t current = 0, total = predictedSize; string temp; bool codeDone = false; - if (progress) + if (progress) { progress->start(total); + } - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } utility::inputStreamSocketAdapter sis(*m_socket); utility::stopSequenceFilteredInputStream <5> sfis1(sis, "\r\n.\r\n"); @@ -274,31 +304,27 @@ size_t POP3Response::readResponseImpl utility::inputStream& is = dfis; - while (!is.eof()) - { + while (!is.eof()) { + // Check whether the time-out delay is elapsed - if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) + if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { throw exceptions::operation_timed_out(); + } } // Receive data from the socket byte_t buffer[65536]; const size_t read = is.read(buffer, sizeof(buffer)); - if (read == 0) // buffer is empty - { - if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) - { + if (read == 0) { // buffer is empty + + if (m_socket->getStatus() & socket::STATUS_WANT_WRITE) { m_socket->waitForWrite(); - } - else if (m_socket->getStatus() & socket::STATUS_WANT_READ) - { + } else if (m_socket->getStatus() & socket::STATUS_WANT_READ) { m_socket->waitForRead(); - } - else - { + } else { // Input stream needs more bytes to continue, but there // is enough data into socket buffer. Do not waitForRead(), // just retry read()ing on the stream. @@ -308,29 +334,30 @@ size_t POP3Response::readResponseImpl } // We have received data: reset the time-out counter - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } // Notify progress current += read; - if (progress) - { + if (progress) { total = std::max(total, current); progress->progress(current, total); } // If we don't have extracted the response code yet - if (!codeDone) - { + if (!codeDone) { + vmime::utility::stringUtils::appendBytesToString(temp, buffer, read); string responseData; - if (stripFirstLine(temp, responseData, &firstLine) == true) - { - if (getResponseCode(firstLine) != CODE_OK) + if (stripFirstLine(temp, responseData, &firstLine) == true) { + + if (getResponseCode(firstLine) != CODE_OK) { throw exceptions::command_error("?", firstLine); + } codeDone = true; @@ -339,61 +366,73 @@ size_t POP3Response::readResponseImpl continue; } - } - else - { + + } else { + // Inject the data into the output stream os.write(buffer, read); } } - if (progress) + if (progress) { progress->stop(total); + } return current; } // static -bool POP3Response::stripFirstLine - (const string& buffer, string& result, string* firstLine) -{ +bool POP3Response::stripFirstLine( + const string& buffer, + string& result, + string* firstLine +) { + const size_t end = buffer.find('\n'); - if (end != string::npos) - { - if (firstLine) *firstLine = utility::stringUtils::trim(buffer.substr(0, end)); + if (end != string::npos) { + + if (firstLine) { + *firstLine = utility::stringUtils::trim(buffer.substr(0, end)); + } + result = buffer.substr(end + 1); + return true; - } - else - { - if (firstLine) *firstLine = utility::stringUtils::trim(buffer); + + } else { + + if (firstLine) { + *firstLine = utility::stringUtils::trim(buffer); + } + result = ""; + return false; } } // static -POP3Response::ResponseCode POP3Response::getResponseCode(const string& buffer) -{ - if (buffer.length() >= 2) - { +POP3Response::ResponseCode POP3Response::getResponseCode(const string& buffer) { + + if (buffer.length() >= 2) { + // +[space] if (buffer[0] == '+' && - (buffer[1] == ' ' || buffer[1] == '\t')) - { + (buffer[1] == ' ' || buffer[1] == '\t')) { + return CODE_READY; } // +OK - if (buffer.length() >= 3) - { + if (buffer.length() >= 3) { + if (buffer[0] == '+' && (buffer[1] == 'O' || buffer[1] == 'o') && - (buffer[2] == 'K' || buffer[1] == 'k')) - { + (buffer[2] == 'K' || buffer[1] == 'k')) { + return CODE_OK; } } @@ -405,37 +444,38 @@ POP3Response::ResponseCode POP3Response::getResponseCode(const string& buffer) // static -void POP3Response::stripResponseCode(const string& buffer, string& result) -{ +void POP3Response::stripResponseCode(const string& buffer, string& result) { + const size_t pos = buffer.find_first_of(" \t"); - if (pos != string::npos) + if (pos != string::npos) { result = buffer.substr(pos + 1); - else + } else { result = buffer; + } } // static -bool POP3Response::checkTerminator(string& buffer, const bool multiLine) -{ +bool POP3Response::checkTerminator(string& buffer, const bool multiLine) { + // Multi-line response - if (multiLine) - { + if (multiLine) { + static const string term1("\r\n.\r\n"); static const string term2("\n.\n"); - return (checkOneTerminator(buffer, term1) || - checkOneTerminator(buffer, term2)); - } + return checkOneTerminator(buffer, term1) || + checkOneTerminator(buffer, term2); + // Normal response - else - { + } else { + static const string term1("\r\n"); static const string term2("\n"); - return (checkOneTerminator(buffer, term1) || - checkOneTerminator(buffer, term2)); + return checkOneTerminator(buffer, term1) || + checkOneTerminator(buffer, term2); } return false; @@ -443,11 +483,11 @@ bool POP3Response::checkTerminator(string& buffer, const bool multiLine) // static -bool POP3Response::checkOneTerminator(string& buffer, const string& term) -{ +bool POP3Response::checkOneTerminator(string& buffer, const string& term) { + if (buffer.length() >= term.length() && - std::equal(buffer.end() - term.length(), buffer.end(), term.begin())) - { + std::equal(buffer.end() - term.length(), buffer.end(), term.begin())) { + buffer.erase(buffer.end() - term.length(), buffer.end()); return true; } diff --git a/src/vmime/net/pop3/POP3Response.hpp b/src/vmime/net/pop3/POP3Response.hpp index 4f0221e6..69f8d5de 100644 --- a/src/vmime/net/pop3/POP3Response.hpp +++ b/src/vmime/net/pop3/POP3Response.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -56,13 +56,12 @@ class POP3Connection; /** A POP3 response, as sent by the server. */ -class VMIME_EXPORT POP3Response : public object -{ +class VMIME_EXPORT POP3Response : public object { + public: /** Possible response codes. */ - enum ResponseCode - { + enum ResponseCode { CODE_OK = 0, CODE_READY, CODE_ERR @@ -100,9 +99,12 @@ public: * @throws exceptions::operation_timed_out if no data * has been received within the granted time */ - static shared_ptr readLargeResponse - (const shared_ptr & conn, utility::outputStream& os, - utility::progressListener* progress, const size_t predictedSize); + static shared_ptr readLargeResponse( + const shared_ptr & conn, + utility::outputStream& os, + utility::progressListener* progress, + const size_t predictedSize + ); /** Returns whether the response is successful ("OK"). @@ -144,12 +146,20 @@ public: private: - POP3Response(const shared_ptr & sok, const shared_ptr & toh, const shared_ptr & tracer); + POP3Response( + const shared_ptr & sok, + const shared_ptr & toh, + const shared_ptr & tracer + ); void readResponseImpl(string& buffer, const bool multiLine); - size_t readResponseImpl - (string& firstLine, utility::outputStream& os, - utility::progressListener* progress, const size_t predictedSize); + + size_t readResponseImpl( + string& firstLine, + utility::outputStream& os, + utility::progressListener* progress, + const size_t predictedSize + ); static bool stripFirstLine(const string& buffer, string& result, string* firstLine); diff --git a/src/vmime/net/pop3/POP3SStore.cpp b/src/vmime/net/pop3/POP3SStore.cpp index 51e58f0e..81a50bc0 100644 --- a/src/vmime/net/pop3/POP3SStore.cpp +++ b/src/vmime/net/pop3/POP3SStore.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,19 +35,22 @@ namespace net { namespace pop3 { -POP3SStore::POP3SStore(const shared_ptr & sess, const shared_ptr & auth) - : POP3Store(sess, auth, true) -{ +POP3SStore::POP3SStore( + const shared_ptr & sess, + const shared_ptr & auth +) + : POP3Store(sess, auth, true) { + } -POP3SStore::~POP3SStore() -{ +POP3SStore::~POP3SStore() { + } -const string POP3SStore::getProtocolName() const -{ +const string POP3SStore::getProtocolName() const { + return "pop3s"; } @@ -58,14 +61,14 @@ const string POP3SStore::getProtocolName() const POP3ServiceInfos POP3SStore::sm_infos(true); -const serviceInfos& POP3SStore::getInfosInstance() -{ +const serviceInfos& POP3SStore::getInfosInstance() { + return sm_infos; } -const serviceInfos& POP3SStore::getInfos() const -{ +const serviceInfos& POP3SStore::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/pop3/POP3SStore.hpp b/src/vmime/net/pop3/POP3SStore.hpp index ad88fa10..76a6ee17 100644 --- a/src/vmime/net/pop3/POP3SStore.hpp +++ b/src/vmime/net/pop3/POP3SStore.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,12 +41,15 @@ namespace pop3 { /** POP3S store service. */ +class VMIME_EXPORT POP3SStore : public POP3Store { -class VMIME_EXPORT POP3SStore : public POP3Store -{ public: - POP3SStore(const shared_ptr & sess, const shared_ptr & auth); + POP3SStore( + const shared_ptr & sess, + const shared_ptr & auth + ); + ~POP3SStore(); const string getProtocolName() const; diff --git a/src/vmime/net/pop3/POP3ServiceInfos.cpp b/src/vmime/net/pop3/POP3ServiceInfos.cpp index 4760d4f2..4deee74d 100644 --- a/src/vmime/net/pop3/POP3ServiceInfos.cpp +++ b/src/vmime/net/pop3/POP3ServiceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,24 +36,24 @@ namespace pop3 { POP3ServiceInfos::POP3ServiceInfos(const bool pop3s) - : m_pop3s(pop3s) -{ + : m_pop3s(pop3s) { + } -const string POP3ServiceInfos::getPropertyPrefix() const -{ - if (m_pop3s) +const string POP3ServiceInfos::getPropertyPrefix() const { + + if (m_pop3s) { return "store.pop3s."; - else + } else { return "store.pop3."; + } } -const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const -{ - static props pop3Props = - { +const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const { + + static props pop3Props = { // POP3-specific options property("options.apop", serviceInfos::property::TYPE_BOOLEAN, "true"), property("options.apop.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"), @@ -75,8 +75,8 @@ const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const property(serviceInfos::property::SERVER_PORT, "110"), }; - static props pop3sProps = - { + static props pop3sProps = { + // POP3-specific options property("options.apop", serviceInfos::property::TYPE_BOOLEAN, "true"), property("options.apop.fallback", serviceInfos::property::TYPE_BOOLEAN, "true"), @@ -102,8 +102,8 @@ const POP3ServiceInfos::props& POP3ServiceInfos::getProperties() const } -const std::vector POP3ServiceInfos::getAvailableProperties() const -{ +const std::vector POP3ServiceInfos::getAvailableProperties() const { + std::vector list; const props& p = getProperties(); @@ -120,8 +120,7 @@ const std::vector POP3ServiceInfos::getAvailablePropert list.push_back(p.PROPERTY_AUTH_PASSWORD); #if VMIME_HAVE_TLS_SUPPORT - if (!m_pop3s) - { + if (!m_pop3s) { list.push_back(p.PROPERTY_CONNECTION_TLS); list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED); } diff --git a/src/vmime/net/pop3/POP3ServiceInfos.hpp b/src/vmime/net/pop3/POP3ServiceInfos.hpp index 710d8be3..590a6bea 100644 --- a/src/vmime/net/pop3/POP3ServiceInfos.hpp +++ b/src/vmime/net/pop3/POP3ServiceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,13 @@ namespace pop3 { /** Information about POP3 service. */ +class VMIME_EXPORT POP3ServiceInfos : public serviceInfos { -class VMIME_EXPORT POP3ServiceInfos : public serviceInfos -{ public: POP3ServiceInfos(const bool pop3s); - struct props - { + struct props { // POP3-specific options serviceInfos::property PROPERTY_OPTIONS_APOP; serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK; diff --git a/src/vmime/net/pop3/POP3Store.cpp b/src/vmime/net/pop3/POP3Store.cpp index 020cc55e..b06640fe 100644 --- a/src/vmime/net/pop3/POP3Store.cpp +++ b/src/vmime/net/pop3/POP3Store.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,125 +42,150 @@ namespace net { namespace pop3 { -POP3Store::POP3Store(const shared_ptr & sess, const shared_ptr & auth, const bool secured) - : store(sess, getInfosInstance(), auth), m_isPOP3S(secured) -{ +POP3Store::POP3Store( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured +) + : store(sess, getInfosInstance(), auth), + m_isPOP3S(secured) { + } -POP3Store::~POP3Store() -{ - try - { - if (isConnected()) +POP3Store::~POP3Store() { + + try { + + if (isConnected()) { disconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -const string POP3Store::getProtocolName() const -{ +const string POP3Store::getProtocolName() const { + return "pop3"; } -shared_ptr POP3Store::getDefaultFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr POP3Store::getDefaultFolder() { - return shared_ptr - (new POP3Folder(folder::path(folder::path::component("INBOX")), - dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new POP3Folder( + folder::path(folder::path::component("INBOX")), + dynamicCast (shared_from_this()) + ) + ); } -shared_ptr POP3Store::getRootFolder() -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr POP3Store::getRootFolder() { - return shared_ptr - (new POP3Folder(folder::path(), dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new POP3Folder( + folder::path(), + dynamicCast (shared_from_this()) + ) + ); } -shared_ptr POP3Store::getFolder(const folder::path& path) -{ - if (!isConnected()) - throw exceptions::illegal_state("Not connected"); +shared_ptr POP3Store::getFolder(const folder::path& path) { - return shared_ptr - (new POP3Folder(path, dynamicCast (shared_from_this()))); + if (!isConnected()) { + throw exceptions::illegal_state("Not connected"); + } + + return shared_ptr ( + new POP3Folder( + path, + dynamicCast (shared_from_this()) + ) + ); } -bool POP3Store::isValidFolderName(const folder::path::component& /* name */) const -{ +bool POP3Store::isValidFolderName(const folder::path::component& /* name */) const { + return true; } -void POP3Store::connect() -{ - if (isConnected()) - throw exceptions::already_connected(); +void POP3Store::connect() { - m_connection = make_shared - (dynamicCast (shared_from_this()), getAuthenticator()); + if (isConnected()) { + throw exceptions::already_connected(); + } + + m_connection = make_shared ( + dynamicCast (shared_from_this()), getAuthenticator() + ); m_connection->connect(); } -bool POP3Store::isPOP3S() const -{ +bool POP3Store::isPOP3S() const { + return m_isPOP3S; } -bool POP3Store::isConnected() const -{ +bool POP3Store::isConnected() const { + return m_connection && m_connection->isConnected(); } -bool POP3Store::isSecuredConnection() const -{ - if (m_connection == NULL) +bool POP3Store::isSecuredConnection() const { + + if (!m_connection) { return false; + } return m_connection->isSecuredConnection(); } -shared_ptr POP3Store::getConnectionInfos() const -{ - if (m_connection == NULL) +shared_ptr POP3Store::getConnectionInfos() const { + + if (!m_connection) { return null; + } return m_connection->getConnectionInfos(); } -shared_ptr POP3Store::getConnection() -{ +shared_ptr POP3Store::getConnection() { + return m_connection; } -void POP3Store::disconnect() -{ - if (!isConnected()) +void POP3Store::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } for (std::list ::iterator it = m_folders.begin() ; - it != m_folders.end() ; ++it) - { + it != m_folders.end() ; ++it) { + (*it)->onStoreDisconnected(); } @@ -172,36 +197,41 @@ void POP3Store::disconnect() } -void POP3Store::noop() -{ - if (!m_connection) +void POP3Store::noop() { + + if (!m_connection) { throw exceptions::not_connected(); + } POP3Command::NOOP()->send(m_connection); shared_ptr response = POP3Response::readResponse(m_connection); - if (!response->isSuccess()) + if (!response->isSuccess()) { throw exceptions::command_error("NOOP", response->getFirstLine()); + } } -void POP3Store::registerFolder(POP3Folder* folder) -{ +void POP3Store::registerFolder(POP3Folder* folder) { + m_folders.push_back(folder); } -void POP3Store::unregisterFolder(POP3Folder* folder) -{ +void POP3Store::unregisterFolder(POP3Folder* folder) { + std::list ::iterator it = std::find(m_folders.begin(), m_folders.end(), folder); - if (it != m_folders.end()) m_folders.erase(it); + + if (it != m_folders.end()) { + m_folders.erase(it); + } } -int POP3Store::getCapabilities() const -{ - return (CAPABILITY_DELETE_MESSAGE); +int POP3Store::getCapabilities() const { + + return CAPABILITY_DELETE_MESSAGE; } @@ -211,14 +241,14 @@ int POP3Store::getCapabilities() const POP3ServiceInfos POP3Store::sm_infos(false); -const serviceInfos& POP3Store::getInfosInstance() -{ +const serviceInfos& POP3Store::getInfosInstance() { + return sm_infos; } -const serviceInfos& POP3Store::getInfos() const -{ +const serviceInfos& POP3Store::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/pop3/POP3Store.hpp b/src/vmime/net/pop3/POP3Store.hpp index 4737715a..140a1ab9 100644 --- a/src/vmime/net/pop3/POP3Store.hpp +++ b/src/vmime/net/pop3/POP3Store.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,15 +51,19 @@ class POP3Response; /** POP3 store service. */ +class VMIME_EXPORT POP3Store : public store { -class VMIME_EXPORT POP3Store : public store -{ friend class POP3Folder; friend class POP3Message; public: - POP3Store(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); + POP3Store( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured = false + ); + ~POP3Store(); const string getProtocolName() const; diff --git a/src/vmime/net/pop3/POP3Utils.cpp b/src/vmime/net/pop3/POP3Utils.cpp index cb17ea9b..b38161e8 100644 --- a/src/vmime/net/pop3/POP3Utils.cpp +++ b/src/vmime/net/pop3/POP3Utils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,24 +39,27 @@ namespace pop3 { // static -void POP3Utils::parseMultiListOrUidlResponse(const shared_ptr & response, std::map & result) -{ +void POP3Utils::parseMultiListOrUidlResponse( + const shared_ptr & response, + std::map & result +) { + std::map ids; - for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) - { + for (size_t i = 0, n = response->getLineCount() ; i < n ; ++i) { + string line = response->getLineAt(i); string::iterator it = line.begin(); - while (it != line.end() && (*it == ' ' || *it == '\t')) + while (it != line.end() && (*it == ' ' || *it == '\t')) { ++it; + } + + if (it != line.end()) { - if (it != line.end()) - { size_t number = 0; - while (it != line.end() && (*it >= '0' && *it <= '9')) - { + while (it != line.end() && (*it >= '0' && *it <= '9')) { number = (number * 10) + (*it - '0'); ++it; } @@ -64,8 +67,7 @@ void POP3Utils::parseMultiListOrUidlResponse(const shared_ptr & re while (it != line.end() && !(*it == ' ' || *it == '\t')) ++it; while (it != line.end() && (*it == ' ' || *it == '\t')) ++it; - if (it != line.end()) - { + if (it != line.end()) { result.insert(std::map ::value_type(number, string(it, line.end()))); } } @@ -74,27 +76,30 @@ void POP3Utils::parseMultiListOrUidlResponse(const shared_ptr & re -class POP3MessageSetEnumerator : public messageSetEnumerator -{ +class POP3MessageSetEnumerator : public messageSetEnumerator { + public: POP3MessageSetEnumerator(const size_t msgCount) - : m_msgCount(msgCount) - { + : m_msgCount(msgCount) { } - void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) - { + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { + size_t last = range.getLast(); - if (last == size_t(-1)) last = m_msgCount; - for (size_t i = range.getFirst() ; i <= last ; ++i) + if (last == size_t(-1)) { + last = m_msgCount; + } + + for (size_t i = range.getFirst() ; i <= last ; ++i) { list.push_back(i); + } } - void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) - { + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& /* range */) { + // Not supported } @@ -109,8 +114,11 @@ private: // static -const std::vector POP3Utils::messageSetToNumberList(const messageSet& msgs, const size_t msgCount) -{ +const std::vector POP3Utils::messageSetToNumberList( + const messageSet& msgs, + const size_t msgCount +) { + POP3MessageSetEnumerator en(msgCount); msgs.enumerate(en); diff --git a/src/vmime/net/pop3/POP3Utils.hpp b/src/vmime/net/pop3/POP3Utils.hpp index b9b2d555..09d15d5b 100644 --- a/src/vmime/net/pop3/POP3Utils.hpp +++ b/src/vmime/net/pop3/POP3Utils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,8 +46,8 @@ namespace pop3 { class POP3Response; -class VMIME_EXPORT POP3Utils -{ +class VMIME_EXPORT POP3Utils { + public: /** Parse a response of type ([integer] [string] \n)*. @@ -63,8 +63,10 @@ public: * @param result points to an associative array which maps a message * number to its corresponding data (either UID or size) */ - static void parseMultiListOrUidlResponse - (const shared_ptr & response, std::map & result); + static void parseMultiListOrUidlResponse( + const shared_ptr & response, + std::map & result + ); /** Returns a list of message numbers given a message set. * @@ -72,7 +74,10 @@ public: * @param msgCount number of messages in folder * @return list of message numbers */ - static const std::vector messageSetToNumberList(const messageSet& msgs, const size_t msgCount); + static const std::vector messageSetToNumberList( + const messageSet& msgs, + const size_t msgCount + ); }; diff --git a/src/vmime/net/pop3/pop3.hpp b/src/vmime/net/pop3/pop3.hpp index 366b1e4a..ced3a97c 100644 --- a/src/vmime/net/pop3/pop3.hpp +++ b/src/vmime/net/pop3/pop3.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/securedConnectionInfos.hpp b/src/vmime/net/securedConnectionInfos.hpp index 8ed8b138..60258018 100644 --- a/src/vmime/net/securedConnectionInfos.hpp +++ b/src/vmime/net/securedConnectionInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ namespace net { /** Information about the secured connection used by a service. */ -class VMIME_EXPORT securedConnectionInfos : public connectionInfos -{ +class VMIME_EXPORT securedConnectionInfos : public connectionInfos { + }; diff --git a/src/vmime/net/sendmail/sendmail.hpp b/src/vmime/net/sendmail/sendmail.hpp index b3692526..a8d1412a 100644 --- a/src/vmime/net/sendmail/sendmail.hpp +++ b/src/vmime/net/sendmail/sendmail.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/sendmail/sendmailServiceInfos.cpp b/src/vmime/net/sendmail/sendmailServiceInfos.cpp index 21cac00c..b8654461 100644 --- a/src/vmime/net/sendmail/sendmailServiceInfos.cpp +++ b/src/vmime/net/sendmail/sendmailServiceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,21 +35,20 @@ namespace net { namespace sendmail { -sendmailServiceInfos::sendmailServiceInfos() -{ +sendmailServiceInfos::sendmailServiceInfos() { + } -const string sendmailServiceInfos::getPropertyPrefix() const -{ +const string sendmailServiceInfos::getPropertyPrefix() const { + return "transport.sendmail."; } -const sendmailServiceInfos::props& sendmailServiceInfos::getProperties() const -{ - static props sendmailProps = - { +const sendmailServiceInfos::props& sendmailServiceInfos::getProperties() const { + + static props sendmailProps = { // Path to sendmail (override default) property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH)) }; @@ -58,8 +57,8 @@ const sendmailServiceInfos::props& sendmailServiceInfos::getProperties() const } -const std::vector sendmailServiceInfos::getAvailableProperties() const -{ +const std::vector sendmailServiceInfos::getAvailableProperties() const { + std::vector list; const props& p = getProperties(); diff --git a/src/vmime/net/sendmail/sendmailServiceInfos.hpp b/src/vmime/net/sendmail/sendmailServiceInfos.hpp index de94e392..bfec2e0c 100644 --- a/src/vmime/net/sendmail/sendmailServiceInfos.hpp +++ b/src/vmime/net/sendmail/sendmailServiceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,13 @@ namespace sendmail { /** Information about sendmail service. */ +class VMIME_EXPORT sendmailServiceInfos : public serviceInfos { -class VMIME_EXPORT sendmailServiceInfos : public serviceInfos -{ public: sendmailServiceInfos(); - struct props - { + struct props { serviceInfos::property PROPERTY_BINPATH; }; diff --git a/src/vmime/net/sendmail/sendmailTransport.cpp b/src/vmime/net/sendmail/sendmailTransport.cpp index b911b129..e39cdd36 100644 --- a/src/vmime/net/sendmail/sendmailTransport.cpp +++ b/src/vmime/net/sendmail/sendmailTransport.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -58,36 +58,42 @@ namespace net { namespace sendmail { -sendmailTransport::sendmailTransport(const shared_ptr & sess, const shared_ptr & auth) - : transport(sess, getInfosInstance(), auth), m_connected(false) -{ +sendmailTransport::sendmailTransport( + const shared_ptr & sess, + const shared_ptr & auth +) + : transport(sess, getInfosInstance(), auth), + m_connected(false) { + } -sendmailTransport::~sendmailTransport() -{ - try - { - if (isConnected()) +sendmailTransport::~sendmailTransport() { + + try { + + if (isConnected()) { disconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -const string sendmailTransport::getProtocolName() const -{ +const string sendmailTransport::getProtocolName() const { + return "sendmail"; } -void sendmailTransport::connect() -{ - if (isConnected()) +void sendmailTransport::connect() { + + if (isConnected()) { throw exceptions::already_connected(); + } // Use the specified path for 'sendmail' or a default one if no path is specified m_sendmailPath = GET_PROPERTY(string, PROPERTY_BINPATH); @@ -96,55 +102,61 @@ void sendmailTransport::connect() } -bool sendmailTransport::isConnected() const -{ - return (m_connected); +bool sendmailTransport::isConnected() const { + + return m_connected; } -bool sendmailTransport::isSecuredConnection() const -{ +bool sendmailTransport::isSecuredConnection() const { + return false; } -shared_ptr sendmailTransport::getConnectionInfos() const -{ +shared_ptr sendmailTransport::getConnectionInfos() const { + return make_shared ("localhost", static_cast (0)); } -void sendmailTransport::disconnect() -{ - if (!isConnected()) +void sendmailTransport::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } internalDisconnect(); } -void sendmailTransport::internalDisconnect() -{ +void sendmailTransport::internalDisconnect() { + m_connected = false; } -void sendmailTransport::noop() -{ +void sendmailTransport::noop() { + // Do nothing } -void sendmailTransport::send - (const mailbox& expeditor, const mailboxList& recipients, - utility::inputStream& is, const size_t size, - utility::progressListener* progress, const mailbox& sender) -{ +void sendmailTransport::send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress, + const mailbox& sender +) { + // If no recipient/expeditor was found, throw an exception - if (recipients.isEmpty()) + if (recipients.isEmpty()) { throw exceptions::no_recipient(); - else if (expeditor.isEmpty()) + } else if (expeditor.isEmpty()) { throw exceptions::no_expeditor(); + } // Construct the argument list std::vector args; @@ -152,38 +164,39 @@ void sendmailTransport::send args.push_back("-i"); args.push_back("-f"); - if (!sender.isEmpty()) + if (!sender.isEmpty()) { args.push_back(expeditor.getEmail().generate()); - else + } else { args.push_back(sender.getEmail().generate()); + } args.push_back("--"); - for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { args.push_back(recipients.getMailboxAt(i)->getEmail().generate()); + } // Call sendmail - try - { + try { internalSend(args, is, size, progress); - } - catch (vmime::exception& e) - { + } catch (vmime::exception& e) { throw exceptions::command_error("SEND", "", "sendmail failed", e); } } -void sendmailTransport::internalSend - (const std::vector & args, utility::inputStream& is, - const size_t size, utility::progressListener* progress) -{ +void sendmailTransport::internalSend( + const std::vector & args, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress +) { + const utility::file::path path = vmime::platform::getHandler()-> getFileSystemFactory()->stringToPath(m_sendmailPath); shared_ptr proc = - vmime::platform::getHandler()-> - getChildProcessFactory()->create(path); + vmime::platform::getHandler()->getChildProcessFactory()->create(path); proc->start(args, utility::childProcess::FLAG_REDIRECT_STDIN); @@ -209,14 +222,14 @@ void sendmailTransport::internalSend sendmailServiceInfos sendmailTransport::sm_infos; -const serviceInfos& sendmailTransport::getInfosInstance() -{ +const serviceInfos& sendmailTransport::getInfosInstance() { + return sm_infos; } -const serviceInfos& sendmailTransport::getInfos() const -{ +const serviceInfos& sendmailTransport::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/sendmail/sendmailTransport.hpp b/src/vmime/net/sendmail/sendmailTransport.hpp index da419f95..76e95726 100644 --- a/src/vmime/net/sendmail/sendmailTransport.hpp +++ b/src/vmime/net/sendmail/sendmailTransport.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,12 +45,15 @@ namespace sendmail { /** Sendmail local transport service. */ +class VMIME_EXPORT sendmailTransport : public transport { -class VMIME_EXPORT sendmailTransport : public transport -{ public: - sendmailTransport(const shared_ptr & sess, const shared_ptr & auth); + sendmailTransport( + const shared_ptr & sess, + const shared_ptr & auth + ); + ~sendmailTransport(); const string getProtocolName() const; @@ -64,13 +67,14 @@ public: void noop(); - void send - (const mailbox& expeditor, - const mailboxList& recipients, - utility::inputStream& is, - const size_t size, - utility::progressListener* progress = NULL, - const mailbox& sender = mailbox()); + void send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox() + ); bool isSecuredConnection() const; shared_ptr getConnectionInfos() const; @@ -79,8 +83,12 @@ private: void internalDisconnect(); - void internalSend(const std::vector & args, utility::inputStream& is, - const size_t size, utility::progressListener* progress); + void internalSend( + const std::vector & args, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress + ); string m_sendmailPath; diff --git a/src/vmime/net/service.cpp b/src/vmime/net/service.cpp index 055f34fa..b43c3e2f 100644 --- a/src/vmime/net/service.cpp +++ b/src/vmime/net/service.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -48,18 +48,20 @@ namespace vmime { namespace net { -service::service(const shared_ptr & sess, const serviceInfos& /* infos */, - const shared_ptr & auth) - : m_session(sess), m_auth(auth) -{ - if (!auth) - { +service::service( + const shared_ptr & sess, + const serviceInfos& /* infos */, + const shared_ptr & auth +) + : m_session(sess), + m_auth(auth) { + + if (!auth) { + #if VMIME_HAVE_SASL_SUPPORT - m_auth = make_shared - (); + m_auth = make_shared (); #else - m_auth = make_shared - (); + m_auth = make_shared (); #endif // VMIME_HAVE_SASL_SUPPORT } @@ -73,89 +75,89 @@ service::service(const shared_ptr & sess, const serviceInfos& /* infos } -service::~service() -{ +service::~service() { + } -shared_ptr service::getSession() const -{ - return (m_session); +shared_ptr service::getSession() const { + + return m_session; } -shared_ptr service::getSession() -{ - return (m_session); +shared_ptr service::getSession() { + + return m_session; } -shared_ptr service::getAuthenticator() const -{ - return (m_auth); +shared_ptr service::getAuthenticator() const { + + return m_auth; } -shared_ptr service::getAuthenticator() -{ - return (m_auth); +shared_ptr service::getAuthenticator() { + + return m_auth; } -void service::setAuthenticator(const shared_ptr & auth) -{ +void service::setAuthenticator(const shared_ptr & auth) { + m_auth = auth; } #if VMIME_HAVE_TLS_SUPPORT -void service::setCertificateVerifier(const shared_ptr & cv) -{ +void service::setCertificateVerifier(const shared_ptr & cv) { + m_certVerifier = cv; } -shared_ptr service::getCertificateVerifier() -{ +shared_ptr service::getCertificateVerifier() { + return m_certVerifier; } #endif // VMIME_HAVE_TLS_SUPPORT -void service::setSocketFactory(const shared_ptr & sf) -{ +void service::setSocketFactory(const shared_ptr & sf) { + m_socketFactory = sf; } -shared_ptr service::getSocketFactory() -{ +shared_ptr service::getSocketFactory() { + return m_socketFactory; } -void service::setTracerFactory(const shared_ptr & tf) -{ +void service::setTracerFactory(const shared_ptr & tf) { + m_tracerFactory = tf; } -shared_ptr service::getTracerFactory() -{ +shared_ptr service::getTracerFactory() { + return m_tracerFactory; } -void service::setTimeoutHandlerFactory(const shared_ptr & thf) -{ +void service::setTimeoutHandlerFactory(const shared_ptr & thf) { + m_toHandlerFactory = thf; } -shared_ptr service::getTimeoutHandlerFactory() -{ +shared_ptr service::getTimeoutHandlerFactory() { + return m_toHandlerFactory; } diff --git a/src/vmime/net/service.hpp b/src/vmime/net/service.hpp index 1fa120d3..bbd2a03d 100644 --- a/src/vmime/net/service.hpp +++ b/src/vmime/net/service.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -55,20 +55,22 @@ namespace net { /** Base class for messaging services. */ +class VMIME_EXPORT service : public object, public enable_shared_from_this { -class VMIME_EXPORT service : public object, public enable_shared_from_this -{ protected: - service(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth); + service( + const shared_ptr & sess, + const serviceInfos& infos, + const shared_ptr & auth + ); public: virtual ~service(); /** Possible service types. */ - enum Type - { + enum Type { TYPE_STORE = 0, /**< The service is a message store. */ TYPE_TRANSPORT /**< The service sends messages. */ }; @@ -198,8 +200,7 @@ public: * @param value property value */ template - void setProperty(const string& name, const TYPE& value) - { + void setProperty(const string& name, const TYPE& value) { m_session->getProperties()[getInfos().getPropertyPrefix() + name] = value; } diff --git a/src/vmime/net/serviceFactory.cpp b/src/vmime/net/serviceFactory.cpp index dc129c63..72b96fef 100644 --- a/src/vmime/net/serviceFactory.cpp +++ b/src/vmime/net/serviceFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,96 +39,103 @@ namespace vmime { namespace net { -serviceFactory::serviceFactory() -{ +serviceFactory::serviceFactory() { + } -serviceFactory::~serviceFactory() -{ +serviceFactory::~serviceFactory() { + } -shared_ptr serviceFactory::getInstance() -{ +shared_ptr serviceFactory::getInstance() { + static serviceFactory instance; return shared_ptr (&instance, noop_shared_ptr_deleter ()); } -shared_ptr serviceFactory::create - (const shared_ptr & sess, const string& protocol, - const shared_ptr & auth) -{ +shared_ptr serviceFactory::create( + const shared_ptr & sess, + const string& protocol, + const shared_ptr & auth +) { + shared_ptr rserv = getServiceByProtocol(protocol); - if (!rserv) + if (!rserv) { throw exceptions::no_factory_available("No service is registered for protocol '" + protocol + "'."); + } return rserv->create(sess, auth); } -shared_ptr serviceFactory::create - (const shared_ptr & sess, const utility::url& u, - const shared_ptr & auth) -{ +shared_ptr serviceFactory::create( + const shared_ptr & sess, + const utility::url& u, + const shared_ptr & auth +) { + shared_ptr serv = create(sess, u.getProtocol(), auth); sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.address"] = u.getHost(); - if (u.getPort() != utility::url::UNSPECIFIED_PORT) + if (u.getPort() != utility::url::UNSPECIFIED_PORT) { sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.port"] = u.getPort(); + } // Path portion of the URL is used to point a specific folder (empty = root). // In maildir, this is used to point to the root of the message repository. - if (!u.getPath().empty()) + if (!u.getPath().empty()) { sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.rootpath"] = u.getPath(); + } - if (!u.getUsername().empty()) - { + if (!u.getUsername().empty()) { sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.username"] = u.getUsername(); sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.password"] = u.getPassword(); } - return (serv); + return serv; } -shared_ptr serviceFactory::getServiceByProtocol(const string& protocol) const -{ +shared_ptr serviceFactory::getServiceByProtocol(const string& protocol) const { + const string name(utility::stringUtils::toLower(protocol)); for (std::vector >::const_iterator it = m_services.begin() ; - it != m_services.end() ; ++it) - { - if ((*it)->getName() == name) + it != m_services.end() ; ++it) { + + if ((*it)->getName() == name) { return (*it); + } } return null; } -size_t serviceFactory::getServiceCount() const -{ - return (m_services.size()); +size_t serviceFactory::getServiceCount() const { + + return m_services.size(); } -shared_ptr serviceFactory::getServiceAt(const size_t pos) const -{ - return (m_services[pos]); +shared_ptr serviceFactory::getServiceAt(const size_t pos) const { + + return m_services[pos]; } -const std::vector > serviceFactory::getServiceList() const -{ +const std::vector > serviceFactory::getServiceList() const { + std::vector > res; for (std::vector >::const_iterator it = m_services.begin() ; - it != m_services.end() ; ++it) - { + it != m_services.end() ; ++it) { + res.push_back(*it); } @@ -136,8 +143,8 @@ const std::vector > servic } -void serviceFactory::registerService(const shared_ptr & reg) -{ +void serviceFactory::registerService(const shared_ptr & reg) { + m_services.push_back(reg); } diff --git a/src/vmime/net/serviceFactory.hpp b/src/vmime/net/serviceFactory.hpp index cb778b91..8911e080 100644 --- a/src/vmime/net/serviceFactory.hpp +++ b/src/vmime/net/serviceFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -58,8 +58,8 @@ class session; /** A factory to create 'service' objects for a specified protocol. */ -class VMIME_EXPORT serviceFactory -{ +class VMIME_EXPORT serviceFactory { + private: serviceFactory(); @@ -70,8 +70,8 @@ public: static shared_ptr getInstance(); /** Information about a registered service. */ - class registeredService : public object - { + class registeredService : public object { + friend class serviceFactory; protected: @@ -80,9 +80,10 @@ public: public: - virtual shared_ptr create - (const shared_ptr & sess, - const shared_ptr & auth) const = 0; + virtual shared_ptr create( + const shared_ptr & sess, + const shared_ptr & auth + ) const = 0; virtual int getType() const = 0; virtual const string& getName() const = 0; @@ -104,10 +105,11 @@ public: * @return a new service instance for the specified protocol, or NULL if no service * is registered for this protocol */ - shared_ptr create - (const shared_ptr & sess, - const string& protocol, - const shared_ptr & auth = null); + shared_ptr create( + const shared_ptr & sess, + const string& protocol, + const shared_ptr & auth = null + ); /** Create a new service instance from a URL. * @@ -118,10 +120,11 @@ public: * @return a new service instance for the specified protocol or NULL if no service * is registered for this protocol */ - shared_ptr create - (const shared_ptr & sess, - const utility::url& u, - const shared_ptr & auth = null); + shared_ptr create( + const shared_ptr & sess, + const utility::url& u, + const shared_ptr & auth = null + ); /** Return information about a registered protocol. * diff --git a/src/vmime/net/serviceInfos.cpp b/src/vmime/net/serviceInfos.cpp index b3fa7d03..6efab13f 100644 --- a/src/vmime/net/serviceInfos.cpp +++ b/src/vmime/net/serviceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,31 +35,49 @@ namespace net { // Common properties -const serviceInfos::property serviceInfos::property::SERVER_ADDRESS - ("server.address", serviceInfos::property::TYPE_STRING); +const serviceInfos::property serviceInfos::property::SERVER_ADDRESS( + "server.address", + serviceInfos::property::TYPE_STRING +); -const serviceInfos::property serviceInfos::property::SERVER_PORT - ("server.port", serviceInfos::property::TYPE_INTEGER); +const serviceInfos::property serviceInfos::property::SERVER_PORT( + "server.port", + serviceInfos::property::TYPE_INTEGER +); -const serviceInfos::property serviceInfos::property::SERVER_ROOTPATH - ("server.rootpath", serviceInfos::property::TYPE_STRING); +const serviceInfos::property serviceInfos::property::SERVER_ROOTPATH( + "server.rootpath", + serviceInfos::property::TYPE_STRING +); -const serviceInfos::property serviceInfos::property::AUTH_USERNAME - ("auth.username", serviceInfos::property::TYPE_STRING); +const serviceInfos::property serviceInfos::property::AUTH_USERNAME( + "auth.username", + serviceInfos::property::TYPE_STRING +); -const serviceInfos::property serviceInfos::property::AUTH_PASSWORD - ("auth.password", serviceInfos::property::TYPE_STRING); +const serviceInfos::property serviceInfos::property::AUTH_PASSWORD( + "auth.password", + serviceInfos::property::TYPE_STRING +); -const serviceInfos::property serviceInfos::property::AUTH_ACCESS_TOKEN - ("auth.accesstoken", serviceInfos::property::TYPE_STRING); +const serviceInfos::property serviceInfos::property::AUTH_ACCESS_TOKEN( + "auth.accesstoken", + serviceInfos::property::TYPE_STRING +); #if VMIME_HAVE_TLS_SUPPORT -const serviceInfos::property serviceInfos::property::CONNECTION_TLS - ("connection.tls", serviceInfos::property::TYPE_BOOLEAN, "false"); +const serviceInfos::property serviceInfos::property::CONNECTION_TLS( + "connection.tls", + serviceInfos::property::TYPE_BOOLEAN, + "false" +); -const serviceInfos::property serviceInfos::property::CONNECTION_TLS_REQUIRED - ("connection.tls.required", serviceInfos::property::TYPE_BOOLEAN, "false"); +const serviceInfos::property serviceInfos::property::CONNECTION_TLS_REQUIRED( + "connection.tls.required", + serviceInfos::property::TYPE_BOOLEAN, + "false" +); #endif // VMIME_HAVE_TLS_SUPPORT @@ -67,29 +85,29 @@ const serviceInfos::property serviceInfos::property::CONNECTION_TLS_REQUIRED // serviceInfos -serviceInfos::serviceInfos() -{ +serviceInfos::serviceInfos() { + } -serviceInfos::serviceInfos(const serviceInfos&) -{ +serviceInfos::serviceInfos(const serviceInfos&) { + } -serviceInfos& serviceInfos::operator=(const serviceInfos&) -{ - return (*this); +serviceInfos& serviceInfos::operator=(const serviceInfos&) { + + return *this; } -serviceInfos::~serviceInfos() -{ +serviceInfos::~serviceInfos() { + } -bool serviceInfos::hasProperty(const shared_ptr & s, const property& p) const -{ +bool serviceInfos::hasProperty(const shared_ptr & s, const property& p) const { + return s->getProperties().hasProperty(getPropertyPrefix() + p.getName()); } @@ -97,18 +115,26 @@ bool serviceInfos::hasProperty(const shared_ptr & s, const property& p) // serviceInfos::property -serviceInfos::property::property - (const string& name, const Types type, - const string& defaultValue, const int flags) - : m_name(name), m_defaultValue(defaultValue), - m_type(type), m_flags(flags) -{ +serviceInfos::property::property( + const string& name, + const Types type, + const string& defaultValue, + const int flags +) + : m_name(name), + m_defaultValue(defaultValue), + m_type(type), + m_flags(flags) { + } -serviceInfos::property::property - (const property& p, const int addFlags, const int removeFlags) -{ +serviceInfos::property::property( + const property& p, + const int addFlags, + const int removeFlags +) { + m_name = p.m_name; m_type = p.m_type; m_defaultValue = p.m_defaultValue; @@ -116,10 +142,13 @@ serviceInfos::property::property } -serviceInfos::property::property - (const property& p, const string& newDefaultValue, - const int addFlags, const int removeFlags) -{ +serviceInfos::property::property( + const property& p, + const string& newDefaultValue, + const int addFlags, + const int removeFlags +) { + m_name = p.m_name; m_type = p.m_type; m_defaultValue = newDefaultValue; @@ -127,38 +156,38 @@ serviceInfos::property::property } -serviceInfos::property& serviceInfos::property::operator=(const property& p) -{ +serviceInfos::property& serviceInfos::property::operator=(const property& p) { + m_name = p.m_name; m_type = p.m_type; m_defaultValue = p.m_defaultValue; m_flags = p.m_flags; - return (*this); + return *this; } -const string& serviceInfos::property::getName() const -{ - return (m_name); +const string& serviceInfos::property::getName() const { + + return m_name; } -const string& serviceInfos::property::getDefaultValue() const -{ - return (m_defaultValue); +const string& serviceInfos::property::getDefaultValue() const { + + return m_defaultValue; } -serviceInfos::property::Types serviceInfos::property::getType() const -{ - return (m_type); +serviceInfos::property::Types serviceInfos::property::getType() const { + + return m_type; } -int serviceInfos::property::getFlags() const -{ - return (m_flags); +int serviceInfos::property::getFlags() const { + + return m_flags; } diff --git a/src/vmime/net/serviceInfos.hpp b/src/vmime/net/serviceInfos.hpp index 63261867..ef7d0f45 100644 --- a/src/vmime/net/serviceInfos.hpp +++ b/src/vmime/net/serviceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,9 +44,8 @@ namespace net { /** Stores information about a messaging service. */ +class VMIME_EXPORT serviceInfos { -class VMIME_EXPORT serviceInfos -{ friend class serviceFactory; protected: @@ -65,8 +64,8 @@ public: /** A service property. */ - class VMIME_EXPORT property - { + class VMIME_EXPORT property { + public: /** The common property 'server.address' which is @@ -114,8 +113,7 @@ public: /** Value types. */ - enum Types - { + enum Types { TYPE_INTEGER, /*< Integer number. */ TYPE_STRING, /*< Character string. */ TYPE_BOOLEAN, /*< Boolean (true or false). */ @@ -125,8 +123,7 @@ public: /** Property flags. */ - enum Flags - { + enum Flags { FLAG_NONE = 0, /*< No flags. */ FLAG_REQUIRED = (1 << 0), /*< The property must be valued. */ FLAG_HIDDEN = (1 << 1), /*< The property should not be shown @@ -143,7 +140,12 @@ public: * @param defaultValue default value * @param flags property attributes */ - property(const string& name, const Types type, const string& defaultValue = "", const int flags = FLAG_DEFAULT); + property( + const string& name, + const Types type, + const string& defaultValue = "", + const int flags = FLAG_DEFAULT + ); /** Construct a new property from an existing property. * @@ -151,7 +153,11 @@ public: * @param addFlags flags to add * @param removeFlags flags to remove */ - property(const property& p, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); + property( + const property& p, + const int addFlags = FLAG_NONE, + const int removeFlags = FLAG_NONE + ); /** Construct a new property from an existing property. * @@ -160,7 +166,12 @@ public: * @param addFlags flags to add * @param removeFlags flags to remove */ - property(const property& p, const string& newDefaultValue, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); + property( + const property& p, + const string& newDefaultValue, + const int addFlags = FLAG_NONE, + const int removeFlags = FLAG_NONE + ); property& operator=(const property& p); @@ -221,13 +232,16 @@ public: * @return value of the property */ template - const TYPE getPropertyValue(const shared_ptr & s, const property& p) const - { - if (p.getFlags() & property::FLAG_REQUIRED) - return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue (); + const TYPE getPropertyValue(const shared_ptr & s, const property& p) const { - return s->getProperties().template getProperty (getPropertyPrefix() + p.getName(), - propertySet::valueFromString (p.getDefaultValue())); + if (p.getFlags() & property::FLAG_REQUIRED) { + return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue (); + } + + return s->getProperties().template getProperty ( + getPropertyPrefix() + p.getName(), + propertySet::valueFromString (p.getDefaultValue()) + ); } /** Helper function to test if the specified property is set in diff --git a/src/vmime/net/serviceRegistration.inl b/src/vmime/net/serviceRegistration.inl index 5a897594..93651999 100644 --- a/src/vmime/net/serviceRegistration.inl +++ b/src/vmime/net/serviceRegistration.inl @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,35 +32,41 @@ namespace net { template -class registeredServiceImpl : public serviceFactory::registeredService -{ +class registeredServiceImpl : public serviceFactory::registeredService { + public: - registeredServiceImpl(const string& name, const int type) - : m_type(type), m_name(name), m_servInfos(S::getInfosInstance()) - { + registeredServiceImpl( + const string& name, + const int type + ) + : m_type(type), + m_name(name), + m_servInfos(S::getInfosInstance()) { + } - shared_ptr create - (const shared_ptr & sess, - const shared_ptr & auth) const - { + shared_ptr create( + const shared_ptr & sess, + const shared_ptr & auth + ) const { + return make_shared (sess, auth); } - const serviceInfos& getInfos() const - { - return (m_servInfos); + const serviceInfos& getInfos() const { + + return m_servInfos; } - const string& getName() const - { - return (m_name); + const string& getName() const { + + return m_name; } - int getType() const - { - return (m_type); + int getType() const { + + return m_type; } private: @@ -73,14 +79,15 @@ private: // Basic service registerer template -class serviceRegisterer -{ +class serviceRegisterer { + public: - serviceRegisterer(const string& protocol, const service::Type type) - { - serviceFactory::getInstance()->registerService - (make_shared >(protocol, type)); + serviceRegisterer(const string& protocol, const service::Type type) { + + serviceFactory::getInstance()->registerService( + make_shared >(protocol, type) + ); } }; diff --git a/src/vmime/net/session.cpp b/src/vmime/net/session.cpp index 9da2fc69..d4b13b47 100644 --- a/src/vmime/net/session.cpp +++ b/src/vmime/net/session.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,8 +38,7 @@ namespace vmime { namespace net { -session::session() -{ +session::session() { #if VMIME_HAVE_TLS_SUPPORT m_tlsProps = make_shared (); @@ -49,8 +48,7 @@ session::session() session::session(const propertySet& props) - : m_props(props) -{ + : m_props(props) { #if VMIME_HAVE_TLS_SUPPORT m_tlsProps = make_shared (); @@ -59,111 +57,123 @@ session::session(const propertySet& props) } -session::~session() -{ +session::~session() { + } // static -shared_ptr session::create() -{ +shared_ptr session::create() { + return shared_ptr (new session()); } // static -shared_ptr session::create(const propertySet& props) -{ +shared_ptr session::create(const propertySet& props) { + return shared_ptr (new session(props)); } -shared_ptr session::getTransport(const shared_ptr & auth) -{ - return (getTransport(m_props["transport.protocol"], auth)); +shared_ptr session::getTransport(const shared_ptr & auth) { + + return getTransport(m_props["transport.protocol"], auth); } -shared_ptr session::getTransport - (const string& protocol, const shared_ptr & auth) -{ +shared_ptr session::getTransport( + const string& protocol, + const shared_ptr & auth +) { + shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, protocol, auth); - if (!sv || sv->getType() != service::TYPE_TRANSPORT) + if (!sv || sv->getType() != service::TYPE_TRANSPORT) { return null; + } return dynamicCast (sv); } -shared_ptr session::getTransport - (const utility::url& url, const shared_ptr & auth) -{ +shared_ptr session::getTransport( + const utility::url& url, + const shared_ptr & auth +) { + shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, url, auth); - if (!sv || sv->getType() != service::TYPE_TRANSPORT) + if (!sv || sv->getType() != service::TYPE_TRANSPORT) { return null; + } return dynamicCast (sv); } -shared_ptr session::getStore(const shared_ptr & auth) -{ - return (getStore(m_props["store.protocol"], auth)); +shared_ptr session::getStore(const shared_ptr & auth) { + + return getStore(m_props["store.protocol"], auth); } -shared_ptr session::getStore - (const string& protocol, const shared_ptr & auth) -{ +shared_ptr session::getStore( + const string& protocol, + const shared_ptr & auth +) { + shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, protocol, auth); - if (!sv || sv->getType() != service::TYPE_STORE) + if (!sv || sv->getType() != service::TYPE_STORE) { return null; + } return dynamicCast (sv); } -shared_ptr session::getStore - (const utility::url& url, const shared_ptr & auth) -{ +shared_ptr session::getStore( + const utility::url& url, + const shared_ptr & auth +) { + shared_ptr sess(dynamicCast (shared_from_this())); shared_ptr sv = serviceFactory::getInstance()->create(sess, url, auth); - if (!sv || sv->getType() != service::TYPE_STORE) + if (!sv || sv->getType() != service::TYPE_STORE) { return null; + } return dynamicCast (sv); } -const propertySet& session::getProperties() const -{ - return (m_props); +const propertySet& session::getProperties() const { + + return m_props; } -propertySet& session::getProperties() -{ - return (m_props); +propertySet& session::getProperties() { + + return m_props; } #if VMIME_HAVE_TLS_SUPPORT -void session::setTLSProperties(const shared_ptr & tlsProps) -{ +void session::setTLSProperties(const shared_ptr & tlsProps) { + m_tlsProps = make_shared (*tlsProps); } -shared_ptr session::getTLSProperties() const -{ +shared_ptr session::getTLSProperties() const { + return m_tlsProps; } diff --git a/src/vmime/net/session.hpp b/src/vmime/net/session.hpp index 75858ef2..7ccd0be6 100644 --- a/src/vmime/net/session.hpp +++ b/src/vmime/net/session.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -53,9 +53,8 @@ class transport; /** An object that contains all the information needed * for connection to a service. */ +class VMIME_EXPORT session : public object, public enable_shared_from_this { -class VMIME_EXPORT session : public object, public enable_shared_from_this -{ public: /** Construct a new session. @@ -84,8 +83,9 @@ public: * @return a new transport service, or NULL if no service is registered for this * protocol or is not a transport protocol */ - shared_ptr getTransport - (const shared_ptr & auth = null); + shared_ptr getTransport( + const shared_ptr & auth = null + ); /** Return a transport service instance for the specified protocol. * @@ -96,9 +96,10 @@ public: * @return a new transport service, or NULL if no service is registered for this * protocol or is not a transport protocol */ - shared_ptr getTransport - (const string& protocol, - const shared_ptr & auth = null); + shared_ptr getTransport( + const string& protocol, + const shared_ptr & auth = null + ); /** Return a transport service instance for the specified URL. * @@ -109,9 +110,10 @@ public: * @return a new transport service, or NULL if no service is registered for this * protocol or is not a transport protocol */ - shared_ptr getTransport - (const utility::url& url, - const shared_ptr & auth = null); + shared_ptr getTransport( + const utility::url& url, + const shared_ptr & auth = null + ); /** Return a transport service instance for the protocol specified * in the session properties. @@ -124,7 +126,9 @@ public: * @return a new store service, or NULL if no service is registered for this * protocol or is not a store protocol */ - shared_ptr getStore(const shared_ptr & auth = null); + shared_ptr getStore( + const shared_ptr & auth = null + ); /** Return a store service instance for the specified protocol. * @@ -135,9 +139,10 @@ public: * @return a new store service, or NULL if no service is registered for this * protocol or is not a store protocol */ - shared_ptr getStore - (const string& protocol, - const shared_ptr & auth = null); + shared_ptr getStore( + const string& protocol, + const shared_ptr & auth = null + ); /** Return a store service instance for the specified URL. * @@ -148,9 +153,10 @@ public: * @return a new store service, or NULL if no service is registered for this * protocol or is not a store protocol */ - shared_ptr getStore - (const utility::url& url, - const shared_ptr & auth = null); + shared_ptr getStore( + const utility::url& url, + const shared_ptr & auth = null + ); /** Properties for the session and for the services. */ diff --git a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp index d1d58e4c..3b242d1b 100644 --- a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,21 +40,31 @@ namespace net { namespace smtp { -SMTPChunkingOutputStreamAdapter::SMTPChunkingOutputStreamAdapter - (const shared_ptr & conn, const size_t size, utility::progressListener* progress) - : m_connection(conn), m_bufferSize(0), m_chunkCount(0), - m_totalSize(size), m_totalSent(0), m_progress(progress) -{ - if (progress) +SMTPChunkingOutputStreamAdapter::SMTPChunkingOutputStreamAdapter( + const shared_ptr & conn, + const size_t size, + utility::progressListener* progress +) + : m_connection(conn), + m_bufferSize(0), + m_chunkCount(0), + m_totalSize(size), + m_totalSent(0), + m_progress(progress) { + + if (progress) { progress->start(size); + } } -void SMTPChunkingOutputStreamAdapter::sendChunk - (const byte_t* const data, const size_t count, const bool last) -{ - if (count == 0 && !last) - { +void SMTPChunkingOutputStreamAdapter::sendChunk( + const byte_t* const data, + const size_t count, + const bool last +) { + + if (count == 0 && !last) { // Nothing to send return; } @@ -65,45 +75,45 @@ void SMTPChunkingOutputStreamAdapter::sendChunk ++m_chunkCount; - if (m_progress) - { + if (m_progress) { + m_totalSent += count; m_totalSize = std::max(m_totalSize, m_totalSent); m_progress->progress(m_totalSent, m_totalSize); } - if (m_connection->getTracer()) + if (m_connection->getTracer()) { m_connection->getTracer()->traceSendBytes(count); + } // If PIPELINING is not supported, read one response for this BDAT command - if (!m_connection->hasExtension("PIPELINING")) - { + if (!m_connection->hasExtension("PIPELINING")) { + shared_ptr resp = m_connection->readResponse(); - if (resp->getCode() != 250) - { + if (resp->getCode() != 250) { m_connection->getTransport()->disconnect(); throw exceptions::command_error("BDAT", resp->getText()); } - } + // If PIPELINING is supported, read one response for each chunk (ie. number // of BDAT commands issued) after the last chunk has been sent - else if (last) - { + } else if (last) { + bool invalidReply = false; shared_ptr resp; - for (unsigned int i = 0 ; i < m_chunkCount ; ++i) - { + for (unsigned int i = 0 ; i < m_chunkCount ; ++i) { + resp = m_connection->readResponse(); - if (resp->getCode() != 250) + if (resp->getCode() != 250) { invalidReply = true; + } } - if (invalidReply) - { + if (invalidReply) { m_connection->getTransport()->disconnect(); throw exceptions::command_error("BDAT", resp->getText()); } @@ -111,14 +121,16 @@ void SMTPChunkingOutputStreamAdapter::sendChunk } -void SMTPChunkingOutputStreamAdapter::writeImpl - (const byte_t* const data, const size_t count) -{ +void SMTPChunkingOutputStreamAdapter::writeImpl( + const byte_t* const data, + const size_t count +) { + const byte_t* curData = data; size_t curCount = count; - while (curCount != 0) - { + while (curCount != 0) { + // Fill the buffer const size_t remaining = sizeof(m_buffer) - m_bufferSize; const size_t bytesToCopy = std::min(remaining, curCount); @@ -130,8 +142,8 @@ void SMTPChunkingOutputStreamAdapter::writeImpl curCount -= bytesToCopy; // If the buffer is full, send this chunk - if (m_bufferSize >= sizeof(m_buffer)) - { + if (m_bufferSize >= sizeof(m_buffer)) { + sendChunk(m_buffer, m_bufferSize, /* last */ false); m_bufferSize = 0; } @@ -139,21 +151,23 @@ void SMTPChunkingOutputStreamAdapter::writeImpl } -void SMTPChunkingOutputStreamAdapter::flush() -{ +void SMTPChunkingOutputStreamAdapter::flush() { + sendChunk(m_buffer, m_bufferSize, /* last */ true); m_bufferSize = 0; - if (m_progress) + if (m_progress) { m_progress->stop(m_totalSize); + } - if (m_connection->getTracer()) + if (m_connection->getTracer()) { m_connection->getTracer()->traceSendBytes(m_bufferSize); + } } -size_t SMTPChunkingOutputStreamAdapter::getBlockSize() -{ +size_t SMTPChunkingOutputStreamAdapter::getBlockSize() { + return sizeof(m_buffer); } diff --git a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp index 7bda1e73..4ef466a2 100644 --- a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,12 +45,15 @@ class SMTPConnection; /** An output stream adapter used with ESMTP CHUNKING extension. */ -class VMIME_EXPORT SMTPChunkingOutputStreamAdapter : public utility::outputStream -{ +class VMIME_EXPORT SMTPChunkingOutputStreamAdapter : public utility::outputStream { + public: - SMTPChunkingOutputStreamAdapter(const shared_ptr & conn, - const size_t size, utility::progressListener* progress); + SMTPChunkingOutputStreamAdapter( + const shared_ptr & conn, + const size_t size, + utility::progressListener* progress + ); void flush(); diff --git a/src/vmime/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index acf59830..8581a994 100644 --- a/src/vmime/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,14 +42,15 @@ namespace smtp { SMTPCommand::SMTPCommand(const string& text, const string& traceText) - : m_text(text), m_traceText(traceText) + : m_text(text), + m_traceText(traceText) { } // static -shared_ptr SMTPCommand::EHLO(const string& hostname) -{ +shared_ptr SMTPCommand::EHLO(const string& hostname) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "EHLO " << hostname; @@ -59,8 +60,8 @@ shared_ptr SMTPCommand::EHLO(const string& hostname) // static -shared_ptr SMTPCommand::HELO(const string& hostname) -{ +shared_ptr SMTPCommand::HELO(const string& hostname) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "HELO " << hostname; @@ -70,8 +71,8 @@ shared_ptr SMTPCommand::HELO(const string& hostname) // static -shared_ptr SMTPCommand::AUTH(const string& mechName) -{ +shared_ptr SMTPCommand::AUTH(const string& mechName) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTH " << mechName; @@ -81,8 +82,8 @@ shared_ptr SMTPCommand::AUTH(const string& mechName) // static -shared_ptr SMTPCommand::AUTH(const string& mechName, const std::string& initialResponse) -{ +shared_ptr SMTPCommand::AUTH(const string& mechName, const std::string& initialResponse) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "AUTH " << mechName << " " << initialResponse; @@ -92,61 +93,63 @@ shared_ptr SMTPCommand::AUTH(const string& mechName, const std::st // static -shared_ptr SMTPCommand::STARTTLS() -{ +shared_ptr SMTPCommand::STARTTLS() { + return createCommand("STARTTLS"); } // static -shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8) -{ +shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8) { + return MAIL(mbox, utf8, 0); } // static -shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, const size_t size) -{ +shared_ptr SMTPCommand::MAIL(const mailbox& mbox, const bool utf8, const size_t size) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "MAIL FROM:<"; - if (utf8) - { + if (utf8) { + cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8); - } - else - { + + } else { + vmime::utility::outputStreamAdapter cmd2(cmd); mbox.getEmail().generate(cmd2); } cmd << ">"; - if (utf8) + if (utf8) { cmd << " SMTPUTF8"; + } - if (size != 0) + if (size != 0) { cmd << " SIZE=" << size; + } return createCommand(cmd.str()); } // static -shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8) -{ +shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "RCPT TO:<"; - if (utf8) - { + if (utf8) { + cmd << mbox.getEmail().toText().getConvertedText(vmime::charsets::UTF_8); - } - else - { + + } else { + vmime::utility::outputStreamAdapter cmd2(cmd); mbox.getEmail().generate(cmd2); } @@ -158,75 +161,78 @@ shared_ptr SMTPCommand::RCPT(const mailbox& mbox, const bool utf8) // static -shared_ptr SMTPCommand::RSET() -{ +shared_ptr SMTPCommand::RSET() { + return createCommand("RSET"); } // static -shared_ptr SMTPCommand::DATA() -{ +shared_ptr SMTPCommand::DATA() { + return createCommand("DATA"); } // static -shared_ptr SMTPCommand::BDAT(const size_t chunkSize, const bool last) -{ +shared_ptr SMTPCommand::BDAT(const size_t chunkSize, const bool last) { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); cmd << "BDAT " << chunkSize; - if (last) + if (last) { cmd << " LAST"; + } return createCommand(cmd.str()); } // static -shared_ptr SMTPCommand::NOOP() -{ +shared_ptr SMTPCommand::NOOP() { + return createCommand("NOOP"); } // static -shared_ptr SMTPCommand::QUIT() -{ +shared_ptr SMTPCommand::QUIT() { + return createCommand("QUIT"); } // static -shared_ptr SMTPCommand::createCommand(const string& text, const string& traceText) -{ - if (traceText.empty()) +shared_ptr SMTPCommand::createCommand(const string& text, const string& traceText) { + + if (traceText.empty()) { return shared_ptr (new SMTPCommand(text, text)); - else + } else { return shared_ptr (new SMTPCommand(text, traceText)); + } } -const string SMTPCommand::getText() const -{ +const string SMTPCommand::getText() const { + return m_text; } -const string SMTPCommand::getTraceText() const -{ +const string SMTPCommand::getTraceText() const { + return m_traceText; } -void SMTPCommand::writeToSocket(const shared_ptr & sok, shared_ptr tr) -{ +void SMTPCommand::writeToSocket(const shared_ptr & sok, shared_ptr tr) { + sok->send(m_text + "\r\n"); - if (tr) + if (tr) { tr->traceSend(m_traceText); + } } diff --git a/src/vmime/net/smtp/SMTPCommand.hpp b/src/vmime/net/smtp/SMTPCommand.hpp index bb52dbc4..137993c4 100644 --- a/src/vmime/net/smtp/SMTPCommand.hpp +++ b/src/vmime/net/smtp/SMTPCommand.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -54,8 +54,8 @@ namespace smtp { /** A SMTP command, as sent to server. */ -class VMIME_EXPORT SMTPCommand : public object -{ +class VMIME_EXPORT SMTPCommand : public object { + public: static shared_ptr HELO(const string& hostname); diff --git a/src/vmime/net/smtp/SMTPCommandSet.cpp b/src/vmime/net/smtp/SMTPCommandSet.cpp index 425b3535..eab7086a 100644 --- a/src/vmime/net/smtp/SMTPCommandSet.cpp +++ b/src/vmime/net/smtp/SMTPCommandSet.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,23 +42,24 @@ namespace smtp { SMTPCommandSet::SMTPCommandSet(const bool pipeline) - : SMTPCommand("", ""), m_pipeline(pipeline), - m_started(false), m_lastCommandSent() -{ + : SMTPCommand("", ""), + m_pipeline(pipeline), + m_started(false), + m_lastCommandSent() { + } // static -shared_ptr SMTPCommandSet::create(const bool pipeline) -{ +shared_ptr SMTPCommandSet::create(const bool pipeline) { + return shared_ptr (new SMTPCommandSet(pipeline)); } -void SMTPCommandSet::addCommand(const shared_ptr & cmd) -{ - if (m_started) - { +void SMTPCommandSet::addCommand(const shared_ptr & cmd) { + + if (m_started) { throw std::runtime_error("Could not add command to pipeline: " "one or more commands have already been sent to the server."); } @@ -67,34 +68,34 @@ void SMTPCommandSet::addCommand(const shared_ptr & cmd) } -void SMTPCommandSet::writeToSocket(const shared_ptr & sok, const shared_ptr & tr) -{ - if (m_pipeline) - { - if (!m_started) - { +void SMTPCommandSet::writeToSocket(const shared_ptr & sok, const shared_ptr & tr) { + + if (m_pipeline) { + + if (!m_started) { + // Send all commands at once for (std::list >::const_iterator it = m_commands.begin() ; - it != m_commands.end() ; ++it) - { + it != m_commands.end() ; ++it) { + shared_ptr cmd = *it; cmd->writeToSocket(sok, tr); } } - if (!m_commands.empty()) - { + if (!m_commands.empty()) { + // Advance the pointer to last command sent shared_ptr cmd = m_commands.front(); m_commands.pop_front(); m_lastCommandSent = cmd; } - } - else - { - if (!m_commands.empty()) - { + + } else { + + if (!m_commands.empty()) { + // Send only one command shared_ptr cmd = m_commands.front(); m_commands.pop_front(); @@ -109,14 +110,14 @@ void SMTPCommandSet::writeToSocket(const shared_ptr & sok, const shared_ } -const string SMTPCommandSet::getText() const -{ +const string SMTPCommandSet::getText() const { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); for (std::list >::const_iterator it = m_commands.begin() ; - it != m_commands.end() ; ++it) - { + it != m_commands.end() ; ++it) { + cmd << (*it)->getText() << "\r\n"; } @@ -124,14 +125,14 @@ const string SMTPCommandSet::getText() const } -const string SMTPCommandSet::getTraceText() const -{ +const string SMTPCommandSet::getTraceText() const { + std::ostringstream cmd; cmd.imbue(std::locale::classic()); for (std::list >::const_iterator it = m_commands.begin() ; - it != m_commands.end() ; ++it) - { + it != m_commands.end() ; ++it) { + cmd << (*it)->getTraceText() << "\r\n"; } @@ -139,14 +140,14 @@ const string SMTPCommandSet::getTraceText() const } -bool SMTPCommandSet::isFinished() const -{ +bool SMTPCommandSet::isFinished() const { + return (m_pipeline && m_started) || (m_commands.size() == 0 && m_started); } -shared_ptr SMTPCommandSet::getLastCommandSent() const -{ +shared_ptr SMTPCommandSet::getLastCommandSent() const { + return m_lastCommandSent; } diff --git a/src/vmime/net/smtp/SMTPCommandSet.hpp b/src/vmime/net/smtp/SMTPCommandSet.hpp index af69366e..2fd977c9 100644 --- a/src/vmime/net/smtp/SMTPCommandSet.hpp +++ b/src/vmime/net/smtp/SMTPCommandSet.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace smtp { /** A set of SMTP commands, which may be sent all at once * to the server if pipelining is supported. */ -class VMIME_EXPORT SMTPCommandSet : public SMTPCommand -{ +class VMIME_EXPORT SMTPCommandSet : public SMTPCommand { + public: /** Creates a new set of SMTP commands. diff --git a/src/vmime/net/smtp/SMTPConnection.cpp b/src/vmime/net/smtp/SMTPConnection.cpp index cad107cb..7680fecf 100644 --- a/src/vmime/net/smtp/SMTPConnection.cpp +++ b/src/vmime/net/smtp/SMTPConnection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -67,37 +67,48 @@ namespace smtp { -SMTPConnection::SMTPConnection(const shared_ptr & transport, const shared_ptr & auth) - : m_transport(transport), m_auth(auth), m_socket(null), m_timeoutHandler(null), - m_authenticated(false), m_secured(false), m_extendedSMTP(false) -{ +SMTPConnection::SMTPConnection( + const shared_ptr & transport, + const shared_ptr & auth +) + : m_transport(transport), + m_auth(auth), + m_socket(null), + m_timeoutHandler(null), + m_authenticated(false), + m_secured(false), + m_extendedSMTP(false) { + static int connectionId = 0; - if (transport->getTracerFactory()) + if (transport->getTracerFactory()) { m_tracer = transport->getTracerFactory()->create(transport, ++connectionId); + } } -SMTPConnection::~SMTPConnection() -{ - try - { - if (isConnected()) +SMTPConnection::~SMTPConnection() { + + try { + + if (isConnected()) { disconnect(); - else if (m_socket) + } else if (m_socket) { internalDisconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -void SMTPConnection::connect() -{ - if (isConnected()) +void SMTPConnection::connect() { + + if (isConnected()) { throw exceptions::already_connected(); + } const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS); const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT); @@ -105,29 +116,30 @@ void SMTPConnection::connect() shared_ptr transport = m_transport.lock(); // Create the time-out handler - if (transport->getTimeoutHandlerFactory()) + if (transport->getTimeoutHandlerFactory()) { m_timeoutHandler = transport->getTimeoutHandlerFactory()->create(); + } // Create and connect the socket m_socket = transport->getSocketFactory()->create(m_timeoutHandler); m_socket->setTracer(m_tracer); #if VMIME_HAVE_TLS_SUPPORT - if (transport->isSMTPS()) // dedicated port/SMTPS - { - shared_ptr tlsSession = tls::TLSSession::create - (transport->getCertificateVerifier(), - transport->getSession()->getTLSProperties()); + if (transport->isSMTPS()) { // dedicated port/SMTPS - shared_ptr tlsSocket = - tlsSession->getSocket(m_socket); + shared_ptr tlsSession = tls::TLSSession::create( + transport->getCertificateVerifier(), + transport->getSession()->getTLSProperties() + ); + + shared_ptr tlsSocket = tlsSession->getSocket(m_socket); m_socket = tlsSocket; m_secured = true; m_cntInfos = make_shared (address, port, tlsSession, tlsSocket); - } - else + + } else #endif // VMIME_HAVE_TLS_SUPPORT { m_cntInfos = make_shared (address, port); @@ -142,8 +154,7 @@ void SMTPConnection::connect() shared_ptr resp; - if ((resp = readResponse())->getCode() != 220) - { + if ((resp = readResponse())->getCode() != 220) { internalDisconnect(); throw exceptions::connection_greeting_error(resp->getText()); } @@ -158,27 +169,24 @@ void SMTPConnection::connect() const bool tlsRequired = HAS_PROPERTY(PROPERTY_CONNECTION_TLS_REQUIRED) && GET_PROPERTY(bool, PROPERTY_CONNECTION_TLS_REQUIRED); - if (!transport->isSMTPS() && tls) // only if not SMTPS - { - try - { + if (!transport->isSMTPS() && tls) { // only if not SMTPS + + try { + startTLS(); - } + // Non-fatal error - catch (exceptions::command_error&) - { - if (tlsRequired) - { + } catch (exceptions::command_error&) { + + if (tlsRequired) { throw; - } - else - { + } else { // TLS is not required, so don't bother } - } + // Fatal error - catch (...) - { + } catch (...) { + throw; } @@ -188,15 +196,16 @@ void SMTPConnection::connect() #endif // VMIME_HAVE_TLS_SUPPORT // Authentication - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH)) + if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH)) { authenticate(); - else + } else { m_authenticated = true; + } } -void SMTPConnection::helo() -{ +void SMTPConnection::helo() { + // First, try Extended SMTP (ESMTP) // // eg: C: EHLO thismachine.ourdomain.com @@ -209,8 +218,8 @@ void SMTPConnection::helo() shared_ptr resp; - if ((resp = readResponse())->getCode() != 250) - { + if ((resp = readResponse())->getCode() != 250) { + // Next, try "Basic" SMTP // // eg: C: HELO thismachine.ourdomain.com @@ -218,24 +227,23 @@ void SMTPConnection::helo() sendRequest(SMTPCommand::HELO(platform::getHandler()->getHostName())); - if ((resp = readResponse())->getCode() != 250) - { + if ((resp = readResponse())->getCode() != 250) { internalDisconnect(); throw exceptions::connection_greeting_error(resp->getLastLine().getText()); } m_extendedSMTP = false; m_extensions.clear(); - } - else - { + + } else { + m_extendedSMTP = true; m_extensions.clear(); // Get supported extensions from SMTP response // One extension per line, format is: EXT PARAM1 PARAM2... - for (size_t i = 1, n = resp->getLineCount() ; i < n ; ++i) - { + for (size_t i = 1, n = resp->getLineCount() ; i < n ; ++i) { + const string line = resp->getLineAt(i).getText(); std::istringstream iss(line); @@ -248,14 +256,15 @@ void SMTPConnection::helo() string param; // Special case: some servers send "AUTH=MECH [MECH MECH...]" - if (ext.length() >= 5 && utility::stringUtils::toUpper(ext.substr(0, 5)) == "AUTH=") - { + if (ext.length() >= 5 && utility::stringUtils::toUpper(ext.substr(0, 5)) == "AUTH=") { + params.push_back(utility::stringUtils::toUpper(ext.substr(5))); ext = "AUTH"; } - while (iss >> param) + while (iss >> param) { params.push_back(utility::stringUtils::toUpper(param)); + } m_extensions[ext] = params; } @@ -263,30 +272,32 @@ void SMTPConnection::helo() } -bool SMTPConnection::hasExtension - (const std::string& extName, std::vector * params) const -{ +bool SMTPConnection::hasExtension( + const std::string& extName, + std::vector * params +) const { + std::map >::const_iterator it = m_extensions.find(extName); - if (it != m_extensions.end()) - { - if (params) + if (it != m_extensions.end()) { + + if (params) { *params = (*it).second; + } return true; - } - else - { + + } else { + return false; } } -void SMTPConnection::authenticate() -{ - if (!m_extendedSMTP) - { +void SMTPConnection::authenticate() { + + if (!m_extendedSMTP) { internalDisconnect(); throw exceptions::command_error("AUTH", "ESMTP not supported."); } @@ -295,17 +306,17 @@ void SMTPConnection::authenticate() #if VMIME_HAVE_SASL_SUPPORT // Try SASL authentication - if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) - { - try - { + if (GET_PROPERTY(bool, PROPERTY_OPTIONS_SASL)) { + + try { + authenticateSASL(); m_authenticated = true; return; - } - catch (exception&) - { + + } catch (exception&) { + internalDisconnect(); throw; } @@ -313,30 +324,36 @@ void SMTPConnection::authenticate() #else // no SASL // allow AUTH PLAIN over TLS - it is a popular and simple mechanism - if (m_secured) - { + if (m_secured) { + std::vector authMechs; hasExtension("AUTH", &authMechs); - if (authMechs.empty()) + if (authMechs.empty()) { throw exceptions::authentication_error("No AUTH mechanism available."); + } const string plain("PLAIN"); - if (std::find(authMechs.begin(), authMechs.end(), plain) != authMechs.end()) - { + + if (std::find(authMechs.begin(), authMechs.end(), plain) != authMechs.end()) { + const string username = getAuthenticator()->getUsername(); const string password = getAuthenticator()->getPassword(); const string authToken = username + '\0' + username + '\0' + password; + auto encoder = new vmime::utility::encoder::b64Encoder(); utility::inputStreamStringAdapter in(authToken); string authTokenBase64; utility::outputStreamStringAdapter out(authTokenBase64); encoder->encode(in, out); + sendRequest(SMTPCommand::AUTH(plain, authTokenBase64)); + shared_ptr response = readResponse(); + const int code = response ? response->getCode() : -1; - if (code == 235) - { + + if (code == 235) { m_authenticated = true; return; } @@ -353,56 +370,61 @@ void SMTPConnection::authenticate() #if VMIME_HAVE_SASL_SUPPORT -void SMTPConnection::authenticateSASL() -{ - if (!dynamicCast (getAuthenticator())) +void SMTPConnection::authenticateSASL() { + + if (!dynamicCast (getAuthenticator())) { throw exceptions::authentication_error("No SASL authenticator available."); + } // Obtain SASL mechanisms supported by server from ESMTP extensions std::vector saslMechs; hasExtension("AUTH", &saslMechs); - if (saslMechs.empty()) + if (saslMechs.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } std::vector > mechList; shared_ptr saslContext = security::sasl::SASLContext::create(); - for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) - { - try - { + for (unsigned int i = 0 ; i < saslMechs.size() ; ++i) { + + try { + mechList.push_back (saslContext->createMechanism(saslMechs[i])); - } - catch (exceptions::no_such_mechanism&) - { + + } catch (exceptions::no_such_mechanism&) { + // Ignore mechanism } } - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try to suggest a mechanism among all those supported shared_ptr suggestedMech = saslContext->suggestMechanism(mechList); - if (!suggestedMech) + if (!suggestedMech) { throw exceptions::authentication_error("Unable to suggest SASL mechanism."); + } // Allow application to choose which mechanisms to use mechList = dynamicCast (getAuthenticator())-> getAcceptableMechanisms(mechList, suggestedMech); - if (mechList.empty()) + if (mechList.empty()) { throw exceptions::authentication_error("No SASL mechanism available."); + } // Try each mechanism in the list in turn - for (unsigned int i = 0 ; i < mechList.size() ; ++i) - { + for (unsigned int i = 0 ; i < mechList.size() ; ++i) { + shared_ptr mech = mechList[i]; shared_ptr saslSession = @@ -410,8 +432,8 @@ void SMTPConnection::authenticateSASL() saslSession->init(); - if (saslSession->getMechanism()->hasInitialResponse()) - { + if (saslSession->getMechanism()->hasInitialResponse()) { + byte_t* initialResp = 0; size_t initialRespLen = 0; @@ -420,100 +442,103 @@ void SMTPConnection::authenticateSASL() string encodedInitialResp(saslContext->encodeB64(initialResp, initialRespLen)); delete [] initialResp; - if (encodedInitialResp.empty()) + if (encodedInitialResp.empty()) { sendRequest(SMTPCommand::AUTH(mech->getName(), "=")); - else + } else { sendRequest(SMTPCommand::AUTH(mech->getName(), encodedInitialResp)); - } - else - { + } + + } else { + sendRequest(SMTPCommand::AUTH(mech->getName())); } - for (bool cont = true ; cont ; ) - { + for (bool cont = true ; cont ; ) { + shared_ptr response = readResponse(); - switch (response->getCode()) - { - case 235: - { - m_socket = saslSession->getSecuredSocket(m_socket); - return; - } - case 334: - { - byte_t* challenge = 0; - size_t challengeLen = 0; + switch (response->getCode()) { - byte_t* resp = 0; - size_t respLen = 0; + case 235: { - try - { - // Extract challenge - saslContext->decodeB64(response->getText(), &challenge, &challengeLen); - - // Prepare response - saslSession->evaluateChallenge - (challenge, challengeLen, &resp, &respLen); - - // Send response - const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; - m_socket->sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); - - if (m_tracer) - m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); + m_socket = saslSession->getSecuredSocket(m_socket); + return; } - catch (exceptions::sasl_exception& e) - { - if (challenge) - { - delete [] challenge; - challenge = NULL; + case 334: { + + byte_t* challenge = 0; + size_t challengeLen = 0; + + byte_t* resp = 0; + size_t respLen = 0; + + try { + + // Extract challenge + saslContext->decodeB64(response->getText(), &challenge, &challengeLen); + + // Prepare response + saslSession->evaluateChallenge(challenge, challengeLen, &resp, &respLen); + + // Send response + const string respB64 = saslContext->encodeB64(resp, respLen) + "\r\n"; + m_socket->sendRaw(utility::stringUtils::bytesFromString(respB64), respB64.length()); + + if (m_tracer) { + m_tracer->traceSendBytes(respB64.length() - 2, "SASL exchange"); + } + + } catch (exceptions::sasl_exception& e) { + + if (challenge) { + delete [] challenge; + challenge = NULL; + } + + if (resp) { + delete [] resp; + resp = NULL; + } + + // Cancel SASL exchange + m_socket->send("*\r\n"); + + if (m_tracer) { + m_tracer->traceSend("*"); + } + + } catch (...) { + + if (challenge) { + delete [] challenge; + } + + if (resp) { + delete [] resp; + } + + throw; } - if (resp) - { - delete [] resp; - resp = NULL; + if (challenge) { + delete [] challenge; } - // Cancel SASL exchange - m_socket->send("*\r\n"); - - if (m_tracer) - m_tracer->traceSend("*"); - } - catch (...) - { - if (challenge) - delete [] challenge; - - if (resp) + if (resp) { delete [] resp; + } - throw; + break; } + default: - if (challenge) - delete [] challenge; - - if (resp) - delete [] resp; - - break; - } - default: - - cont = false; - break; + cont = false; + break; } } } - throw exceptions::authentication_error - ("Could not authenticate using SASL: all mechanisms failed."); + throw exceptions::authentication_error("Could not authenticate using SASL: all mechanisms failed."); } #endif // VMIME_HAVE_SASL_SUPPORT @@ -521,42 +546,44 @@ void SMTPConnection::authenticateSASL() #if VMIME_HAVE_TLS_SUPPORT -void SMTPConnection::startTLS() -{ - try - { +void SMTPConnection::startTLS() { + + try { + sendRequest(SMTPCommand::STARTTLS()); shared_ptr resp = readResponse(); - if (resp->getCode() != 220) - { - throw SMTPCommandError("STARTTLS", resp->getText(), - resp->getCode(), resp->getEnhancedCode()); + if (resp->getCode() != 220) { + + throw SMTPCommandError( + "STARTTLS", resp->getText(), resp->getCode(), resp->getEnhancedCode() + ); } - shared_ptr tlsSession = tls::TLSSession::create - (getTransport()->getCertificateVerifier(), - getTransport()->getSession()->getTLSProperties()); + shared_ptr tlsSession = tls::TLSSession::create( + getTransport()->getCertificateVerifier(), + getTransport()->getSession()->getTLSProperties() + ); - shared_ptr tlsSocket = - tlsSession->getSocket(m_socket); + shared_ptr tlsSocket = tlsSession->getSocket(m_socket); tlsSocket->handshake(); m_socket = tlsSocket; m_secured = true; - m_cntInfos = make_shared - (m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket); - } - catch (exceptions::command_error&) - { + m_cntInfos = make_shared ( + m_cntInfos->getHost(), m_cntInfos->getPort(), tlsSession, tlsSocket + ); + + } catch (exceptions::command_error&) { + // Non-fatal error throw; - } - catch (exception&) - { + + } catch (exception&) { + // Fatal error internalDisconnect(); throw; @@ -566,28 +593,29 @@ void SMTPConnection::startTLS() #endif // VMIME_HAVE_TLS_SUPPORT -void SMTPConnection::disconnect() -{ - if (!isConnected()) +void SMTPConnection::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } internalDisconnect(); } -void SMTPConnection::internalDisconnect() -{ - if (isConnected()) - { - try - { +void SMTPConnection::internalDisconnect() { + + if (isConnected()) { + + try { + sendRequest(SMTPCommand::QUIT()); // Do not wait for server response. This is contrary to the RFC, but // some servers never send a response to a QUIT command. - } - catch (exception&) - { + + } catch (exception&) { + // Not important } } @@ -605,16 +633,17 @@ void SMTPConnection::internalDisconnect() } -void SMTPConnection::sendRequest(const shared_ptr & cmd) -{ +void SMTPConnection::sendRequest(const shared_ptr & cmd) { + cmd->writeToSocket(m_socket, m_tracer); } -shared_ptr SMTPConnection::readResponse() -{ - shared_ptr resp = SMTPResponse::readResponse - (m_tracer, m_socket, m_timeoutHandler, m_responseState); +shared_ptr SMTPConnection::readResponse() { + + shared_ptr resp = SMTPResponse::readResponse( + m_tracer, m_socket, m_timeoutHandler, m_responseState + ); m_responseState = resp->getCurrentState(); @@ -622,56 +651,56 @@ shared_ptr SMTPConnection::readResponse() } -bool SMTPConnection::isConnected() const -{ +bool SMTPConnection::isConnected() const { + return m_socket && m_socket->isConnected() && m_authenticated; } -bool SMTPConnection::isSecuredConnection() const -{ +bool SMTPConnection::isSecuredConnection() const { + return m_secured; } -shared_ptr SMTPConnection::getConnectionInfos() const -{ +shared_ptr SMTPConnection::getConnectionInfos() const { + return m_cntInfos; } -shared_ptr SMTPConnection::getTransport() -{ +shared_ptr SMTPConnection::getTransport() { + return m_transport.lock(); } -shared_ptr SMTPConnection::getSession() -{ +shared_ptr SMTPConnection::getSession() { + return m_transport.lock()->getSession(); } -shared_ptr SMTPConnection::getSocket() -{ +shared_ptr SMTPConnection::getSocket() { + return m_socket; } -shared_ptr SMTPConnection::getTracer() -{ +shared_ptr SMTPConnection::getTracer() { + return m_tracer; } -shared_ptr SMTPConnection::getTimeoutHandler() -{ +shared_ptr SMTPConnection::getTimeoutHandler() { + return m_timeoutHandler; } -shared_ptr SMTPConnection::getAuthenticator() -{ +shared_ptr SMTPConnection::getAuthenticator() { + return m_auth; } diff --git a/src/vmime/net/smtp/SMTPConnection.hpp b/src/vmime/net/smtp/SMTPConnection.hpp index 50f5daf2..d8a2375e 100644 --- a/src/vmime/net/smtp/SMTPConnection.hpp +++ b/src/vmime/net/smtp/SMTPConnection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -61,12 +61,16 @@ class SMTPTransport; /** Manage connection to a SMTP server. */ -class VMIME_EXPORT SMTPConnection : public object -{ +class VMIME_EXPORT SMTPConnection : public object { + public: - SMTPConnection(const shared_ptr & transport, const shared_ptr & auth); - virtual ~SMTPConnection(); + SMTPConnection( + const shared_ptr & transport, + const shared_ptr & auth + ); + + ~SMTPConnection(); virtual void connect(); diff --git a/src/vmime/net/smtp/SMTPExceptions.cpp b/src/vmime/net/smtp/SMTPExceptions.cpp index 0c3112c0..641632c5 100644 --- a/src/vmime/net/smtp/SMTPExceptions.cpp +++ b/src/vmime/net/smtp/SMTPExceptions.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,52 +39,60 @@ namespace smtp { // SMTPCommandError // -SMTPCommandError::SMTPCommandError - (const string& command, const string& response, - const string& desc, const int statusCode, - const SMTPResponse::enhancedStatusCode& extendedStatusCode, - const exception& other) +SMTPCommandError::SMTPCommandError( + const string& command, + const string& response, + const string& desc, + const int statusCode, + const SMTPResponse::enhancedStatusCode& extendedStatusCode, + const exception& other +) : command_error(command, response, desc, other), - m_status(statusCode), m_exStatus(extendedStatusCode) -{ + m_status(statusCode), + m_exStatus(extendedStatusCode) { + } -SMTPCommandError::SMTPCommandError - (const string& command, const string& response, - const int statusCode, const SMTPResponse::enhancedStatusCode& extendedStatusCode, - const exception& other) +SMTPCommandError::SMTPCommandError( + const string& command, + const string& response, + const int statusCode, + const SMTPResponse::enhancedStatusCode& extendedStatusCode, + const exception& other +) : command_error(command, response, "", other), - m_status(statusCode), m_exStatus(extendedStatusCode) -{ + m_status(statusCode), + m_exStatus(extendedStatusCode) { + } -SMTPCommandError::~SMTPCommandError() throw() -{ +SMTPCommandError::~SMTPCommandError() throw() { + } -int SMTPCommandError::statusCode() const -{ +int SMTPCommandError::statusCode() const { + return m_status; } -const SMTPResponse::enhancedStatusCode SMTPCommandError::extendedStatusCode() const -{ +const SMTPResponse::enhancedStatusCode SMTPCommandError::extendedStatusCode() const { + return m_exStatus; } -exception* SMTPCommandError::clone() const -{ +exception* SMTPCommandError::clone() const { + return new SMTPCommandError(*this); } -const char* SMTPCommandError::name() const throw() -{ +const char* SMTPCommandError::name() const throw() { + return "SMTPCommandError"; } @@ -94,24 +102,24 @@ const char* SMTPCommandError::name() const throw() // SMTPMessageSizeExceedsMaxLimitsException::SMTPMessageSizeExceedsMaxLimitsException(const exception& other) - : net_exception("Message size exceeds maximum server limits (permanent error).", other) -{ + : net_exception("Message size exceeds maximum server limits (permanent error).", other) { + } -SMTPMessageSizeExceedsMaxLimitsException::~SMTPMessageSizeExceedsMaxLimitsException() throw() -{ +SMTPMessageSizeExceedsMaxLimitsException::~SMTPMessageSizeExceedsMaxLimitsException() throw() { + } -exception* SMTPMessageSizeExceedsMaxLimitsException::clone() const -{ +exception* SMTPMessageSizeExceedsMaxLimitsException::clone() const { + return new SMTPMessageSizeExceedsMaxLimitsException(*this); } -const char* SMTPMessageSizeExceedsMaxLimitsException::name() const throw() -{ +const char* SMTPMessageSizeExceedsMaxLimitsException::name() const throw() { + return "SMTPMessageSizeExceedsMaxLimitsException"; } @@ -121,24 +129,24 @@ const char* SMTPMessageSizeExceedsMaxLimitsException::name() const throw() // SMTPMessageSizeExceedsCurLimitsException::SMTPMessageSizeExceedsCurLimitsException(const exception& other) - : net_exception("Message size exceeds current server limits (temporary storage error).", other) -{ + : net_exception("Message size exceeds current server limits (temporary storage error).", other) { + } -SMTPMessageSizeExceedsCurLimitsException::~SMTPMessageSizeExceedsCurLimitsException() throw() -{ +SMTPMessageSizeExceedsCurLimitsException::~SMTPMessageSizeExceedsCurLimitsException() throw() { + } -exception* SMTPMessageSizeExceedsCurLimitsException::clone() const -{ +exception* SMTPMessageSizeExceedsCurLimitsException::clone() const { + return new SMTPMessageSizeExceedsCurLimitsException(*this); } -const char* SMTPMessageSizeExceedsCurLimitsException::name() const throw() -{ +const char* SMTPMessageSizeExceedsCurLimitsException::name() const throw() { + return "SMTPMessageSizeExceedsCurLimitsException"; } diff --git a/src/vmime/net/smtp/SMTPExceptions.hpp b/src/vmime/net/smtp/SMTPExceptions.hpp index 75842042..70f1e113 100644 --- a/src/vmime/net/smtp/SMTPExceptions.hpp +++ b/src/vmime/net/smtp/SMTPExceptions.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,19 +44,25 @@ namespace smtp { /** SMTP Command error: a SMTP command failed. */ +class VMIME_EXPORT SMTPCommandError : public exceptions::command_error { -class VMIME_EXPORT SMTPCommandError : public exceptions::command_error -{ public: - SMTPCommandError(const string& command, const string& response, - const string& desc, const int statusCode, + SMTPCommandError( + const string& command, + const string& response, + const string& desc, + const int statusCode, const SMTPResponse::enhancedStatusCode& extendedStatusCode, - const exception& other = NO_EXCEPTION); + const exception& other = NO_EXCEPTION + ); - SMTPCommandError(const string& command, const string& response, + SMTPCommandError( + const string& command, + const string& response, const int statusCode, const SMTPResponse::enhancedStatusCode& extendedStatusCode, - const exception& other = NO_EXCEPTION); + const exception& other = NO_EXCEPTION + ); ~SMTPCommandError() throw(); @@ -87,9 +93,8 @@ private: /** SMTP error: message size exceeds maximum server limits. * This is a permanent error. */ +class VMIME_EXPORT SMTPMessageSizeExceedsMaxLimitsException : public exceptions::net_exception { -class VMIME_EXPORT SMTPMessageSizeExceedsMaxLimitsException : public exceptions::net_exception -{ public: SMTPMessageSizeExceedsMaxLimitsException(const exception& other = NO_EXCEPTION); @@ -103,9 +108,8 @@ public: /** SMTP error: message size exceeds current server limits. * This is a temporary error (you may retry later). */ +class VMIME_EXPORT SMTPMessageSizeExceedsCurLimitsException : public exceptions::net_exception { -class VMIME_EXPORT SMTPMessageSizeExceedsCurLimitsException : public exceptions::net_exception -{ public: SMTPMessageSizeExceedsCurLimitsException(const exception& other = NO_EXCEPTION); diff --git a/src/vmime/net/smtp/SMTPResponse.cpp b/src/vmime/net/smtp/SMTPResponse.cpp index d1c25cf8..22347053 100644 --- a/src/vmime/net/smtp/SMTPResponse.cpp +++ b/src/vmime/net/smtp/SMTPResponse.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,50 +44,57 @@ namespace net { namespace smtp { -SMTPResponse::SMTPResponse - (const shared_ptr & tr, const shared_ptr & sok, - const shared_ptr & toh, const state& st) - : m_socket(sok), m_timeoutHandler(toh), m_tracer(tr), - m_responseBuffer(st.responseBuffer), m_responseContinues(false) -{ +SMTPResponse::SMTPResponse( + const shared_ptr & tr, + const shared_ptr & sok, + const shared_ptr & toh, + const state& st +) + : m_socket(sok), + m_timeoutHandler(toh), + m_tracer(tr), + m_responseBuffer(st.responseBuffer), + m_responseContinues(false) { + } SMTPResponse::SMTPResponse(const SMTPResponse&) - : vmime::object() -{ + : vmime::object() { + // Not used } -int SMTPResponse::getCode() const -{ +int SMTPResponse::getCode() const { + const int firstCode = m_lines[0].getCode(); - for (unsigned int i = 1 ; i < m_lines.size() ; ++i) - { + for (unsigned int i = 1 ; i < m_lines.size() ; ++i) { + // All response codes returned must be equal // or else this in an error... - if (m_lines[i].getCode() != firstCode) + if (m_lines[i].getCode() != firstCode) { return 0; + } } return firstCode; } -const SMTPResponse::enhancedStatusCode SMTPResponse::getEnhancedCode() const -{ +const SMTPResponse::enhancedStatusCode SMTPResponse::getEnhancedCode() const { + return m_lines[m_lines.size() - 1].getEnhancedCode(); } -const string SMTPResponse::getText() const -{ +const string SMTPResponse::getText() const { + string text = m_lines[0].getText(); - for (unsigned int i = 1 ; i < m_lines.size() ; ++i) - { + for (unsigned int i = 1 ; i < m_lines.size() ; ++i) { + text += '\n'; text += m_lines[i].getText(); } @@ -97,10 +104,13 @@ const string SMTPResponse::getText() const // static -shared_ptr SMTPResponse::readResponse - (const shared_ptr & tr, const shared_ptr & sok, - const shared_ptr & toh, const state& st) -{ +shared_ptr SMTPResponse::readResponse( + const shared_ptr & tr, + const shared_ptr & sok, + const shared_ptr & toh, + const state& st +) { + shared_ptr resp = shared_ptr (new SMTPResponse(tr, sok, toh, st)); @@ -110,54 +120,57 @@ shared_ptr SMTPResponse::readResponse } -void SMTPResponse::readResponse() -{ +void SMTPResponse::readResponse() { + responseLine line = getNextResponse(); m_lines.push_back(line); - while (m_responseContinues) - { + while (m_responseContinues) { line = getNextResponse(); m_lines.push_back(line); } } -const string SMTPResponse::readResponseLine() -{ +const string SMTPResponse::readResponseLine() { + string currentBuffer = m_responseBuffer; - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } + + while (true) { - while (true) - { // Get a line from the response buffer const size_t lineEnd = currentBuffer.find_first_of('\n'); - if (lineEnd != string::npos) - { + if (lineEnd != string::npos) { + size_t actualLineEnd = lineEnd; - if (actualLineEnd != 0 && currentBuffer[actualLineEnd - 1] == '\r') // CRLF case + if (actualLineEnd != 0 && currentBuffer[actualLineEnd - 1] == '\r') { // CRLF case actualLineEnd--; + } const string line(currentBuffer.begin(), currentBuffer.begin() + actualLineEnd); currentBuffer.erase(currentBuffer.begin(), currentBuffer.begin() + lineEnd + 1); m_responseBuffer = currentBuffer; - if (m_tracer) + if (m_tracer) { m_tracer->traceReceive(line); + } return line; } // Check whether the time-out delay is elapsed - if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) + if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { throw exceptions::operation_timed_out(); + } m_timeoutHandler->resetTimeOut(); } @@ -166,8 +179,7 @@ const string SMTPResponse::readResponseLine() string receiveBuffer; m_socket->receive(receiveBuffer); - if (receiveBuffer.empty()) // buffer is empty - { + if (receiveBuffer.empty()) { // buffer is empty m_socket->waitForRead(); continue; } @@ -177,8 +189,8 @@ const string SMTPResponse::readResponseLine() } -const SMTPResponse::responseLine SMTPResponse::getNextResponse() -{ +const SMTPResponse::responseLine SMTPResponse::getNextResponse() { + string line = readResponseLine(); const int code = extractResponseCode(line); @@ -186,22 +198,23 @@ const SMTPResponse::responseLine SMTPResponse::getNextResponse() m_responseContinues = (line.length() >= 4 && line[3] == '-'); - if (line.length() > 4) + if (line.length() > 4) { text = utility::stringUtils::trim(line.substr(4)); - else + } else { text = ""; + } return responseLine(code, text, extractEnhancedCode(text)); } // static -int SMTPResponse::extractResponseCode(const string& response) -{ +int SMTPResponse::extractResponseCode(const string& response) { + int code = 0; - if (response.length() >= 3) - { + if (response.length() >= 3) { + code = (response[0] - '0') * 100 + (response[1] - '0') * 10 + (response[2] - '0'); @@ -212,23 +225,23 @@ int SMTPResponse::extractResponseCode(const string& response) // static -const SMTPResponse::enhancedStatusCode SMTPResponse::extractEnhancedCode(const string& responseText) -{ +const SMTPResponse::enhancedStatusCode SMTPResponse::extractEnhancedCode(const string& responseText) { + enhancedStatusCode enhCode; std::istringstream iss(responseText); iss.imbue(std::locale::classic()); - if (std::isdigit(iss.peek())) - { + if (std::isdigit(iss.peek())) { + iss >> enhCode.klass; - if (iss.get() == '.' && std::isdigit(iss.peek())) - { + if (iss.get() == '.' && std::isdigit(iss.peek())) { + iss >> enhCode.subject; - if (iss.get() == '.' && std::isdigit(iss.peek())) - { + if (iss.get() == '.' && std::isdigit(iss.peek())) { + iss >> enhCode.detail; return enhCode; } @@ -239,26 +252,26 @@ const SMTPResponse::enhancedStatusCode SMTPResponse::extractEnhancedCode(const s } -const SMTPResponse::responseLine SMTPResponse::getLineAt(const size_t pos) const -{ +const SMTPResponse::responseLine SMTPResponse::getLineAt(const size_t pos) const { + return m_lines[pos]; } -size_t SMTPResponse::getLineCount() const -{ +size_t SMTPResponse::getLineCount() const { + return m_lines.size(); } -const SMTPResponse::responseLine SMTPResponse::getLastLine() const -{ +const SMTPResponse::responseLine SMTPResponse::getLastLine() const { + return m_lines[m_lines.size() - 1]; } -const SMTPResponse::state SMTPResponse::getCurrentState() const -{ +const SMTPResponse::state SMTPResponse::getCurrentState() const { + state st; st.responseBuffer = m_responseBuffer; @@ -269,44 +282,50 @@ const SMTPResponse::state SMTPResponse::getCurrentState() const // SMTPResponse::responseLine -SMTPResponse::responseLine::responseLine(const int code, const string& text, const enhancedStatusCode& enhCode) - : m_code(code), m_text(text), m_enhCode(enhCode) -{ +SMTPResponse::responseLine::responseLine( + const int code, + const string& text, + const enhancedStatusCode& enhCode +) + : m_code(code), + m_text(text), + m_enhCode(enhCode) { + } -void SMTPResponse::responseLine::setCode(const int code) -{ +void SMTPResponse::responseLine::setCode(const int code) { + m_code = code; } -int SMTPResponse::responseLine::getCode() const -{ +int SMTPResponse::responseLine::getCode() const { + return m_code; } -void SMTPResponse::responseLine::setEnhancedCode(const enhancedStatusCode& enhCode) -{ +void SMTPResponse::responseLine::setEnhancedCode(const enhancedStatusCode& enhCode) { + m_enhCode = enhCode; } -const SMTPResponse::enhancedStatusCode SMTPResponse::responseLine::getEnhancedCode() const -{ +const SMTPResponse::enhancedStatusCode SMTPResponse::responseLine::getEnhancedCode() const { + return m_enhCode; } -void SMTPResponse::responseLine::setText(const string& text) -{ +void SMTPResponse::responseLine::setText(const string& text) { + m_text = text; } -const string SMTPResponse::responseLine::getText() const -{ +const string SMTPResponse::responseLine::getText() const { + return m_text; } @@ -316,19 +335,23 @@ const string SMTPResponse::responseLine::getText() const SMTPResponse::enhancedStatusCode::enhancedStatusCode() - : klass(0), subject(0), detail(0) -{ + : klass(0), + subject(0), + detail(0) { + } SMTPResponse::enhancedStatusCode::enhancedStatusCode(const enhancedStatusCode& enhCode) - : klass(enhCode.klass), subject(enhCode.subject), detail(enhCode.detail) -{ + : klass(enhCode.klass), + subject(enhCode.subject), + detail(enhCode.detail) { + } -std::ostream& operator<<(std::ostream& os, const SMTPResponse::enhancedStatusCode& code) -{ +std::ostream& operator<<(std::ostream& os, const SMTPResponse::enhancedStatusCode& code) { + os << code.klass << '.' << code.subject << '.' << code.detail; return os; } diff --git a/src/vmime/net/smtp/SMTPResponse.hpp b/src/vmime/net/smtp/SMTPResponse.hpp index fa19a1db..2eec7f4d 100644 --- a/src/vmime/net/smtp/SMTPResponse.hpp +++ b/src/vmime/net/smtp/SMTPResponse.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,19 +49,19 @@ namespace smtp { /** A SMTP response, as sent by the server. */ -class VMIME_EXPORT SMTPResponse : public object -{ +class VMIME_EXPORT SMTPResponse : public object { + public: /** Current state of response parser. */ - struct state - { + struct state { + string responseBuffer; }; /** Enhanced status code (as per RFC-3463). */ - struct enhancedStatusCode - { + struct enhancedStatusCode { + enhancedStatusCode(); enhancedStatusCode(const enhancedStatusCode& enhCode); @@ -71,8 +71,8 @@ public: }; /** An element of a SMTP response. */ - class responseLine - { + class responseLine { + public: responseLine(const int code, const string& text, const enhancedStatusCode& enhCode); @@ -104,9 +104,12 @@ public: * @throws exceptions::operation_timed_out if no data * has been received within the granted time */ - static shared_ptr readResponse - (const shared_ptr & tr, const shared_ptr & sok, - const shared_ptr & toh, const state& st); + static shared_ptr readResponse( + const shared_ptr & tr, + const shared_ptr & sok, + const shared_ptr & toh, + const state& st + ); /** Return the SMTP response code. * @@ -154,7 +157,13 @@ public: private: - SMTPResponse(const shared_ptr & tr, const shared_ptr & sok, const shared_ptr & toh, const state& st); + SMTPResponse( + const shared_ptr & tr, + const shared_ptr & sok, + const shared_ptr & toh, + const state& st + ); + SMTPResponse(const SMTPResponse&); void readResponse(); diff --git a/src/vmime/net/smtp/SMTPSTransport.cpp b/src/vmime/net/smtp/SMTPSTransport.cpp index 1a8a0804..5158aa98 100644 --- a/src/vmime/net/smtp/SMTPSTransport.cpp +++ b/src/vmime/net/smtp/SMTPSTransport.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,19 +35,22 @@ namespace net { namespace smtp { -SMTPSTransport::SMTPSTransport(const shared_ptr & sess, const shared_ptr & auth) - : SMTPTransport(sess, auth, true) -{ +SMTPSTransport::SMTPSTransport( + const shared_ptr & sess, + const shared_ptr & auth +) + : SMTPTransport(sess, auth, true) { + } -SMTPSTransport::~SMTPSTransport() -{ +SMTPSTransport::~SMTPSTransport() { + } -const string SMTPSTransport::getProtocolName() const -{ +const string SMTPSTransport::getProtocolName() const { + return "smtps"; } @@ -58,14 +61,14 @@ const string SMTPSTransport::getProtocolName() const SMTPServiceInfos SMTPSTransport::sm_infos(true); -const serviceInfos& SMTPSTransport::getInfosInstance() -{ +const serviceInfos& SMTPSTransport::getInfosInstance() { + return sm_infos; } -const serviceInfos& SMTPSTransport::getInfos() const -{ +const serviceInfos& SMTPSTransport::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/smtp/SMTPSTransport.hpp b/src/vmime/net/smtp/SMTPSTransport.hpp index 52dce1f2..f19b3c55 100644 --- a/src/vmime/net/smtp/SMTPSTransport.hpp +++ b/src/vmime/net/smtp/SMTPSTransport.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,12 +41,15 @@ namespace smtp { /** SMTPS transport service. */ +class VMIME_EXPORT SMTPSTransport : public SMTPTransport { -class VMIME_EXPORT SMTPSTransport : public SMTPTransport -{ public: - SMTPSTransport(const shared_ptr & sess, const shared_ptr & auth); + SMTPSTransport( + const shared_ptr & sess, + const shared_ptr & auth + ); + ~SMTPSTransport(); const string getProtocolName() const; diff --git a/src/vmime/net/smtp/SMTPServiceInfos.cpp b/src/vmime/net/smtp/SMTPServiceInfos.cpp index 532bb8b8..a2ee3d57 100644 --- a/src/vmime/net/smtp/SMTPServiceInfos.cpp +++ b/src/vmime/net/smtp/SMTPServiceInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,24 +36,24 @@ namespace smtp { SMTPServiceInfos::SMTPServiceInfos(const bool smtps) - : m_smtps(smtps) -{ + : m_smtps(smtps) { + } -const string SMTPServiceInfos::getPropertyPrefix() const -{ - if (m_smtps) +const string SMTPServiceInfos::getPropertyPrefix() const { + + if (m_smtps) { return "transport.smtps."; - else + } else { return "transport.smtp."; + } } -const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const -{ - static props smtpProps = - { +const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const { + + static props smtpProps = { // SMTP-specific options property("options.need-authentication", serviceInfos::property::TYPE_BOOLEAN, "false"), #if VMIME_HAVE_SASL_SUPPORT @@ -77,8 +77,7 @@ const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const property(serviceInfos::property::SERVER_PORT, "25"), }; - static props smtpsProps = - { + static props smtpsProps = { // SMTP-specific options property("options.need-authentication", serviceInfos::property::TYPE_BOOLEAN, "false"), #if VMIME_HAVE_SASL_SUPPORT @@ -106,8 +105,8 @@ const SMTPServiceInfos::props& SMTPServiceInfos::getProperties() const } -const std::vector SMTPServiceInfos::getAvailableProperties() const -{ +const std::vector SMTPServiceInfos::getAvailableProperties() const { + std::vector list; const props& p = getProperties(); @@ -123,8 +122,7 @@ const std::vector SMTPServiceInfos::getAvailablePropert list.push_back(p.PROPERTY_AUTH_PASSWORD); #if VMIME_HAVE_TLS_SUPPORT - if (!m_smtps) - { + if (!m_smtps) { list.push_back(p.PROPERTY_CONNECTION_TLS); list.push_back(p.PROPERTY_CONNECTION_TLS_REQUIRED); } diff --git a/src/vmime/net/smtp/SMTPServiceInfos.hpp b/src/vmime/net/smtp/SMTPServiceInfos.hpp index f783194d..005a0a21 100644 --- a/src/vmime/net/smtp/SMTPServiceInfos.hpp +++ b/src/vmime/net/smtp/SMTPServiceInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,13 @@ namespace smtp { /** Information about SMTP service. */ +class VMIME_EXPORT SMTPServiceInfos : public serviceInfos { -class VMIME_EXPORT SMTPServiceInfos : public serviceInfos -{ public: SMTPServiceInfos(const bool smtps); - struct props - { + struct props { // SMTP-specific options serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH; #if VMIME_HAVE_SASL_SUPPORT diff --git a/src/vmime/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index 27afcf6f..72cba7c7 100644 --- a/src/vmime/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,116 +51,126 @@ namespace net { namespace smtp { -SMTPTransport::SMTPTransport(const shared_ptr & sess, const shared_ptr & auth, const bool secured) - : transport(sess, getInfosInstance(), auth), m_isSMTPS(secured), m_needReset(false) -{ +SMTPTransport::SMTPTransport( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured +) + : transport(sess, getInfosInstance(), auth), + m_isSMTPS(secured), + m_needReset(false) { + } -SMTPTransport::~SMTPTransport() -{ - try - { - if (isConnected()) +SMTPTransport::~SMTPTransport() { + + try { + + if (isConnected()) { disconnect(); - } - catch (...) - { + } + + } catch (...) { + // Don't throw in destructor } } -const string SMTPTransport::getProtocolName() const -{ +const string SMTPTransport::getProtocolName() const { + return "smtp"; } -bool SMTPTransport::isSMTPS() const -{ +bool SMTPTransport::isSMTPS() const { + return m_isSMTPS; } -void SMTPTransport::connect() -{ - if (isConnected()) - throw exceptions::already_connected(); +void SMTPTransport::connect() { - m_connection = make_shared - (dynamicCast (shared_from_this()), getAuthenticator()); + if (isConnected()) { + throw exceptions::already_connected(); + } + + m_connection = make_shared ( + dynamicCast (shared_from_this()), getAuthenticator() + ); m_connection->connect(); } -bool SMTPTransport::isConnected() const -{ +bool SMTPTransport::isConnected() const { + return m_connection && m_connection->isConnected(); } -bool SMTPTransport::isSecuredConnection() const -{ - if (m_connection == NULL) +bool SMTPTransport::isSecuredConnection() const { + + if (!m_connection) { return false; + } return m_connection->isSecuredConnection(); } -shared_ptr SMTPTransport::getConnectionInfos() const -{ - if (m_connection == NULL) +shared_ptr SMTPTransport::getConnectionInfos() const { + + if (!m_connection) { return null; + } return m_connection->getConnectionInfos(); } -shared_ptr SMTPTransport::getConnection() -{ +shared_ptr SMTPTransport::getConnection() { + return m_connection; } -void SMTPTransport::disconnect() -{ - if (!isConnected()) +void SMTPTransport::disconnect() { + + if (!isConnected()) { throw exceptions::not_connected(); + } m_connection->disconnect(); m_connection = null; } -void SMTPTransport::noop() -{ - if (!isConnected()) +void SMTPTransport::noop() { + + if (!isConnected()) { throw exceptions::not_connected(); + } m_connection->sendRequest(SMTPCommand::NOOP()); shared_ptr resp = m_connection->readResponse(); - if (resp->getCode() != 250) - { - throw SMTPCommandError - ("NOOP", resp->getText(), resp->getCode(), resp->getEnhancedCode()); + if (resp->getCode() != 250) { + throw SMTPCommandError("NOOP", resp->getText(), resp->getCode(), resp->getEnhancedCode()); } } // static -bool SMTPTransport::mailboxNeedsUTF8(const mailbox& mb) -{ +bool SMTPTransport::mailboxNeedsUTF8(const mailbox& mb) { + bool all7bit = utility::stringUtils::is7bit(mb.getEmail().getLocalName().getBuffer()) && utility::stringUtils::is7bit(mb.getEmail().getDomainName().getBuffer()); - for (size_t i = 0, n = mb.getName().getWordCount() ; all7bit && i != n ; ++i) - { + for (size_t i = 0, n = mb.getName().getWordCount() ; all7bit && i != n ; ++i) { all7bit = utility::stringUtils::is7bit(mb.getName().getWordAt(i)->getBuffer()); } @@ -168,16 +178,19 @@ bool SMTPTransport::mailboxNeedsUTF8(const mailbox& mb) } -void SMTPTransport::sendEnvelope - (const mailbox& expeditor, const mailboxList& recipients, - const mailbox& sender, bool sendDATACommand, - const size_t size) -{ +void SMTPTransport::sendEnvelope( + const mailbox& expeditor, + const mailboxList& recipients, + const mailbox& sender, + bool sendDATACommand, + const size_t size +) { // If no recipient/expeditor was found, throw an exception - if (recipients.isEmpty()) + if (recipients.isEmpty()) { throw exceptions::no_recipient(); - else if (expeditor.isEmpty()) + } else if (expeditor.isEmpty()) { throw exceptions::no_expeditor(); + } const bool needReset = m_needReset; @@ -189,20 +202,22 @@ void SMTPTransport::sendEnvelope shared_ptr commands = SMTPCommandSet::create(hasPipelining); // Emit a "RSET" command if we previously sent a message on this connection - if (needReset) + if (needReset) { commands->addCommand(SMTPCommand::RSET()); + } // Check whether we need SMTPUTF8 const bool hasSMTPUTF8 = m_connection->hasExtension("SMTPUTF8"); bool needSMTPUTF8 = false; - if (!sender.isEmpty()) + if (!sender.isEmpty()) { needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(sender); - else + } else { needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(expeditor); + } + + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { - for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) - { const mailbox& mbox = *recipients.getMailboxAt(i); needSMTPUTF8 = needSMTPUTF8 || mailboxNeedsUTF8(mbox); } @@ -210,16 +225,16 @@ void SMTPTransport::sendEnvelope // Emit the "MAIL" command const bool hasSize = m_connection->hasExtension("SIZE"); - if (!sender.isEmpty()) - { + if (!sender.isEmpty()) { + commands->addCommand( SMTPCommand::MAIL( sender, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0 ) ); - } - else - { + + } else { + commands->addCommand( SMTPCommand::MAIL( expeditor, hasSMTPUTF8 && needSMTPUTF8, hasSize ? size : 0 @@ -231,119 +246,141 @@ void SMTPTransport::sendEnvelope m_needReset = true; // Emit a "RCPT TO" command for each recipient - for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) - { + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { + const mailbox& mbox = *recipients.getMailboxAt(i); commands->addCommand(SMTPCommand::RCPT(mbox, hasSMTPUTF8 && needSMTPUTF8)); } // Prepare sending of message data - if (sendDATACommand) + if (sendDATACommand) { commands->addCommand(SMTPCommand::DATA()); + } // Read response for "RSET" command - if (needReset) - { + if (needReset) { + commands->writeToSocket(m_connection->getSocket(), m_connection->getTracer()); resp = m_connection->readResponse(); if (resp->getCode() != 250 && - resp->getCode() != 200) // RFC-876: << In reply to a RSET and/or a NOOP command, - // some servers reply "200" >> - { + resp->getCode() != 200) { // RFC-876: << In reply to a RSET and/or a NOOP command, + // some servers reply "200" >> + disconnect(); - throw SMTPCommandError - (commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode()); + throw SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ); } } // Read response for "MAIL" command commands->writeToSocket(m_connection->getSocket(), m_connection->getTracer()); - if ((resp = m_connection->readResponse())->getCode() != 250) - { + if ((resp = m_connection->readResponse())->getCode() != 250) { + // SIZE extension: insufficient system storage - if (resp->getCode() == 452) - { - throw SMTPMessageSizeExceedsCurLimitsException - (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode())); - } + if (resp->getCode() == 452) { + + throw SMTPMessageSizeExceedsCurLimitsException( + SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ) + ); + // SIZE extension: message size exceeds fixed maximum message size - else if (resp->getCode() == 552) - { - throw SMTPMessageSizeExceedsMaxLimitsException - (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode())); - } + } else if (resp->getCode() == 552) { + + throw SMTPMessageSizeExceedsMaxLimitsException( + SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ) + ); + // Other error - else - { - throw SMTPCommandError - (commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode()); + } else { + + throw SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ); } } // Read responses for "RCPT TO" commands - for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) - { + for (size_t i = 0 ; i < recipients.getMailboxCount() ; ++i) { + commands->writeToSocket(m_connection->getSocket(), m_connection->getTracer()); resp = m_connection->readResponse(); if (resp->getCode() != 250 && - resp->getCode() != 251) - { + resp->getCode() != 251) { + // SIZE extension: insufficient system storage - if (resp->getCode() == 452) - { - throw SMTPMessageSizeExceedsCurLimitsException - (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode())); - } + if (resp->getCode() == 452) { + + throw SMTPMessageSizeExceedsCurLimitsException( + SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ) + ); + // SIZE extension: message size exceeds fixed maximum message size - else if (resp->getCode() == 552) - { - throw SMTPMessageSizeExceedsMaxLimitsException - (SMTPCommandError(commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode())); - } + } else if (resp->getCode() == 552) { + + throw SMTPMessageSizeExceedsMaxLimitsException( + SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ) + ); + // Other error - else - { - throw SMTPCommandError - (commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode()); + } else { + + throw SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ); } } } // Read response for "DATA" command - if (sendDATACommand) - { + if (sendDATACommand) { + commands->writeToSocket(m_connection->getSocket(), m_connection->getTracer()); - if ((resp = m_connection->readResponse())->getCode() != 354) - { - throw SMTPCommandError - (commands->getLastCommandSent()->getText(), resp->getText(), - resp->getCode(), resp->getEnhancedCode()); + if ((resp = m_connection->readResponse())->getCode() != 354) { + + throw SMTPCommandError( + commands->getLastCommandSent()->getText(), resp->getText(), + resp->getCode(), resp->getEnhancedCode() + ); } } } -void SMTPTransport::send - (const mailbox& expeditor, const mailboxList& recipients, - utility::inputStream& is, const size_t size, - utility::progressListener* progress, const mailbox& sender) -{ - if (!isConnected()) +void SMTPTransport::send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress, + const mailbox& sender +) { + + if (!isConnected()) { throw exceptions::not_connected(); + } // Send message envelope sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ true, size); @@ -360,28 +397,30 @@ void SMTPTransport::send // Send end-of-data delimiter m_connection->getSocket()->send("\r\n.\r\n"); - if (m_connection->getTracer()) - { + if (m_connection->getTracer()) { m_connection->getTracer()->traceSendBytes(size); m_connection->getTracer()->traceSend("."); } shared_ptr resp; - if ((resp = m_connection->readResponse())->getCode() != 250) - { - throw SMTPCommandError - ("DATA", resp->getText(), resp->getCode(), resp->getEnhancedCode()); + if ((resp = m_connection->readResponse())->getCode() != 250) { + throw SMTPCommandError("DATA", resp->getText(), resp->getCode(), resp->getEnhancedCode()); } } -void SMTPTransport::send - (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, - utility::progressListener* progress, const mailbox& sender) -{ - if (!isConnected()) +void SMTPTransport::send( + const shared_ptr & msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress, + const mailbox& sender +) { + + if (!isConnected()) { throw exceptions::not_connected(); + } // Generate the message with Internationalized Email support, // if this is supported by the SMTP server @@ -392,9 +431,8 @@ void SMTPTransport::send // buffer then use the send() method which takes an inputStream if (!m_connection->hasExtension("CHUNKING") || !getInfos().getPropertyValue (getSession(), - dynamic_cast (getInfos()).getProperties().PROPERTY_OPTIONS_CHUNKING)) + dynamic_cast (getInfos()).getProperties().PROPERTY_OPTIONS_CHUNKING)) { - { std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); @@ -411,8 +449,7 @@ void SMTPTransport::send // Send message envelope const size_t msgSize = msg->getGeneratedSize(ctx); - sendEnvelope(expeditor, recipients, sender, - /* sendDATACommand */ false, msgSize); + sendEnvelope(expeditor, recipients, sender, /* sendDATACommand */ false, msgSize); // Send the message by chunks SMTPChunkingOutputStreamAdapter chunkStream(m_connection, msgSize, progress); @@ -429,14 +466,14 @@ void SMTPTransport::send SMTPServiceInfos SMTPTransport::sm_infos(false); -const serviceInfos& SMTPTransport::getInfosInstance() -{ +const serviceInfos& SMTPTransport::getInfosInstance() { + return sm_infos; } -const serviceInfos& SMTPTransport::getInfos() const -{ +const serviceInfos& SMTPTransport::getInfos() const { + return sm_infos; } diff --git a/src/vmime/net/smtp/SMTPTransport.hpp b/src/vmime/net/smtp/SMTPTransport.hpp index a5f15ca6..67c63a55 100644 --- a/src/vmime/net/smtp/SMTPTransport.hpp +++ b/src/vmime/net/smtp/SMTPTransport.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,12 +49,16 @@ class SMTPCommand; /** SMTP transport service. */ +class VMIME_EXPORT SMTPTransport : public transport { -class VMIME_EXPORT SMTPTransport : public transport -{ public: - SMTPTransport(const shared_ptr & sess, const shared_ptr & auth, const bool secured = false); + SMTPTransport( + const shared_ptr & sess, + const shared_ptr & auth, + const bool secured = false + ); + ~SMTPTransport(); const string getProtocolName() const; @@ -68,20 +72,22 @@ public: void noop(); - void send - (const mailbox& expeditor, - const mailboxList& recipients, - utility::inputStream& is, - const size_t size, - utility::progressListener* progress = NULL, - const mailbox& sender = mailbox()); + void send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox() + ); - void send - (const shared_ptr & msg, - const mailbox& expeditor, - const mailboxList& recipients, - utility::progressListener* progress = NULL, - const mailbox& sender = mailbox()); + void send( + const shared_ptr & msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox() + ); bool isSecuredConnection() const; shared_ptr getConnectionInfos() const; @@ -103,12 +109,13 @@ private: * @param sendDATACommand if true, the DATA command will be sent * @param size message size, in bytes (or 0, if not known) */ - void sendEnvelope - (const mailbox& expeditor, - const mailboxList& recipients, - const mailbox& sender, - bool sendDATACommand, - const size_t size); + void sendEnvelope( + const mailbox& expeditor, + const mailboxList& recipients, + const mailbox& sender, + bool sendDATACommand, + const size_t size + ); shared_ptr m_connection; diff --git a/src/vmime/net/smtp/smtp.hpp b/src/vmime/net/smtp/smtp.hpp index 2a9ee312..4c0b17d7 100644 --- a/src/vmime/net/smtp/smtp.hpp +++ b/src/vmime/net/smtp/smtp.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/socket.hpp b/src/vmime/net/socket.hpp index 4de45ca9..a236a9f3 100644 --- a/src/vmime/net/socket.hpp +++ b/src/vmime/net/socket.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,13 +43,11 @@ namespace net { /** Interface for connecting to servers. */ +class VMIME_EXPORT socket : public object { -class VMIME_EXPORT socket : public object -{ public: - enum Status - { + enum Status { STATUS_WOULDBLOCK = 0xf, /**< The operation would block. Retry later. */ STATUS_WANT_READ = 0x1, /**< The socket wants to read data, retry when data is available. */ STATUS_WANT_WRITE = 0x2 /**< The socket wants to write data, retry when data can be written. */ @@ -195,9 +193,8 @@ private: /** A class to create 'socket' objects. */ +class socketFactory : public object { -class socketFactory : public object -{ public: virtual ~socketFactory() { } diff --git a/src/vmime/net/store.hpp b/src/vmime/net/store.hpp index dfeb9a53..49b8ca3b 100644 --- a/src/vmime/net/store.hpp +++ b/src/vmime/net/store.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,13 +42,18 @@ namespace net { /** A store service. * Encapsulate protocols that provide access to user's mail drop. */ +class VMIME_EXPORT store : public service { -class VMIME_EXPORT store : public service -{ protected: - store(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth) - : service(sess, infos, auth) { } + store( + const shared_ptr & sess, + const serviceInfos& infos, + const shared_ptr & auth + ) + : service(sess, infos, auth) { + + } public: @@ -81,8 +86,7 @@ public: virtual bool isValidFolderName(const folder::path::component& name) const = 0; /** Store capabilities. */ - enum Capabilities - { + enum Capabilities { CAPABILITY_CREATE_FOLDER = (1 << 0), /**< Can create folders. */ CAPABILITY_RENAME_FOLDER = (1 << 1), /**< Can rename folders. */ CAPABILITY_ADD_MESSAGE = (1 << 2), /**< Can append message to folders. */ @@ -101,7 +105,10 @@ public: virtual int getCapabilities() const = 0; - Type getType() const { return (TYPE_STORE); } + Type getType() const { + + return TYPE_STORE; + } }; diff --git a/src/vmime/net/timeoutHandler.hpp b/src/vmime/net/timeoutHandler.hpp index 397cc796..fed1bc48 100644 --- a/src/vmime/net/timeoutHandler.hpp +++ b/src/vmime/net/timeoutHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,9 +42,8 @@ namespace net { * to stop operations that takes too much time to complete (ie. no data * received from the server for a long time if the network link is down). */ +class VMIME_EXPORT timeoutHandler : public object { -class VMIME_EXPORT timeoutHandler : public object -{ public: virtual ~timeoutHandler() { } @@ -71,9 +70,8 @@ public: /** A class to create 'timeoutHandler' objects. */ +class timeoutHandlerFactory : public object { -class timeoutHandlerFactory : public object -{ public: virtual ~timeoutHandlerFactory() { } diff --git a/src/vmime/net/tls/TLSProperties.cpp b/src/vmime/net/tls/TLSProperties.cpp index 1986db79..f7721d40 100644 --- a/src/vmime/net/tls/TLSProperties.cpp +++ b/src/vmime/net/tls/TLSProperties.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/tls/TLSProperties.hpp b/src/vmime/net/tls/TLSProperties.hpp index 0dbc8f05..94341cae 100644 --- a/src/vmime/net/tls/TLSProperties.hpp +++ b/src/vmime/net/tls/TLSProperties.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ namespace tls { /** Holds options for a TLS session. */ -class VMIME_EXPORT TLSProperties : public object -{ +class VMIME_EXPORT TLSProperties : public object { + public: TLSProperties(); @@ -50,8 +50,8 @@ public: /** Predefined generic cipher suites (work with all TLS libraries). */ - enum GenericCipherSuite - { + enum GenericCipherSuite { + CIPHERSUITE_HIGH, /**< High encryption cipher suites (> 128 bits). */ CIPHERSUITE_MEDIUM, /**< Medium encryption cipher suites (>= 128 bits). */ CIPHERSUITE_LOW, /**< Low encryption cipher suites (>= 64 bits). */ diff --git a/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp index 45b9527e..055dfea0 100644 --- a/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,29 +36,34 @@ namespace net { namespace tls { -TLSSecuredConnectionInfos::TLSSecuredConnectionInfos - (const string& host, const port_t port, - const shared_ptr & tlsSession, const shared_ptr & tlsSocket) - : m_host(host), m_port(port), - m_tlsSession(tlsSession), m_tlsSocket(tlsSocket) -{ +TLSSecuredConnectionInfos::TLSSecuredConnectionInfos( + const string& host, + const port_t port, + const shared_ptr & tlsSession, + const shared_ptr & tlsSocket +) + : m_host(host), + m_port(port), + m_tlsSession(tlsSession), + m_tlsSocket(tlsSocket) { + } -const string TLSSecuredConnectionInfos::getHost() const -{ +const string TLSSecuredConnectionInfos::getHost() const { + return m_host; } -port_t TLSSecuredConnectionInfos::getPort() const -{ +port_t TLSSecuredConnectionInfos::getPort() const { + return m_port; } -shared_ptr TLSSecuredConnectionInfos::getPeerCertificates() const -{ +shared_ptr TLSSecuredConnectionInfos::getPeerCertificates() const { + return m_tlsSocket->getPeerCertificates(); } diff --git a/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp index 19e7a064..c65e9d26 100644 --- a/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,12 +47,16 @@ class TLSSocket; /** Information about a TLS-secured connection used by a service. */ -class VMIME_EXPORT TLSSecuredConnectionInfos : public securedConnectionInfos -{ +class VMIME_EXPORT TLSSecuredConnectionInfos : public securedConnectionInfos { + public: - TLSSecuredConnectionInfos(const string& host, const port_t port, - const shared_ptr & tlsSession, const shared_ptr & tlsSocket); + TLSSecuredConnectionInfos( + const string& host, + const port_t port, + const shared_ptr & tlsSession, + const shared_ptr & tlsSocket + ); const string getHost() const; port_t getPort() const; diff --git a/src/vmime/net/tls/TLSSession.cpp b/src/vmime/net/tls/TLSSession.cpp index a46f07ca..ab8b7c3a 100644 --- a/src/vmime/net/tls/TLSSession.cpp +++ b/src/vmime/net/tls/TLSSession.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ namespace net { namespace tls { -TLSSession::TLSSession() -{ +TLSSession::TLSSession() { + } diff --git a/src/vmime/net/tls/TLSSession.hpp b/src/vmime/net/tls/TLSSession.hpp index 83a1623c..9e84fe76 100644 --- a/src/vmime/net/tls/TLSSession.hpp +++ b/src/vmime/net/tls/TLSSession.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,8 +46,8 @@ namespace tls { /** Describe a TLS connection between a client and a server. */ -class VMIME_EXPORT TLSSession : public object, public enable_shared_from_this -{ +class VMIME_EXPORT TLSSession : public object, public enable_shared_from_this { + public: /** Create and initialize a new TLS session. @@ -57,7 +57,10 @@ public: * @param props TLS properties for this session * @return a new TLS session */ - static shared_ptr create(const shared_ptr & cv, const shared_ptr & props); + static shared_ptr create( + const shared_ptr & cv, + const shared_ptr & props + ); /** Create a new socket that adds a TLS security layer around * an existing socket. You should create only one socket diff --git a/src/vmime/net/tls/TLSSocket.cpp b/src/vmime/net/tls/TLSSocket.cpp index 0419a571..fbca0820 100644 --- a/src/vmime/net/tls/TLSSocket.cpp +++ b/src/vmime/net/tls/TLSSocket.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/net/tls/TLSSocket.hpp b/src/vmime/net/tls/TLSSocket.hpp index 75b80116..ca50aa8e 100644 --- a/src/vmime/net/tls/TLSSocket.hpp +++ b/src/vmime/net/tls/TLSSocket.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,8 +49,8 @@ class TLSSession; /** Add a TLS security layer to an existing socket. */ -class VMIME_EXPORT TLSSocket : public socket -{ +class VMIME_EXPORT TLSSocket : public socket { + public: /** Create a new socket object that adds a security layer diff --git a/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp index 36ab7d7a..b2996fb3 100644 --- a/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,63 +42,63 @@ namespace tls { TLSProperties::TLSProperties() - : m_data(make_shared ()) -{ + : m_data(make_shared ()) { + setCipherSuite(CIPHERSUITE_DEFAULT); } TLSProperties::TLSProperties(const TLSProperties& props) : object(), - m_data(make_shared ()) -{ + m_data(make_shared ()) { + *dynamicCast (m_data) = *dynamicCast (props.m_data); } -void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite) -{ - switch (cipherSuite) - { - case CIPHERSUITE_HIGH: +void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite) { - setCipherSuite("SECURE256:%SSL3_RECORD_VERSION"); - break; + switch (cipherSuite) { - case CIPHERSUITE_MEDIUM: + case CIPHERSUITE_HIGH: - setCipherSuite("SECURE128:%SSL3_RECORD_VERSION"); - break; + setCipherSuite("SECURE256:%SSL3_RECORD_VERSION"); + break; - case CIPHERSUITE_LOW: + case CIPHERSUITE_MEDIUM: - setCipherSuite("NORMAL:%SSL3_RECORD_VERSION"); - break; + setCipherSuite("SECURE128:%SSL3_RECORD_VERSION"); + break; - default: - case CIPHERSUITE_DEFAULT: + case CIPHERSUITE_LOW: - setCipherSuite("NORMAL:%SSL3_RECORD_VERSION"); - break; + setCipherSuite("NORMAL:%SSL3_RECORD_VERSION"); + break; + + default: + case CIPHERSUITE_DEFAULT: + + setCipherSuite("NORMAL:%SSL3_RECORD_VERSION"); + break; } } -void TLSProperties::setCipherSuite(const string& cipherSuite) -{ +void TLSProperties::setCipherSuite(const string& cipherSuite) { + dynamicCast (m_data)->cipherSuite = cipherSuite; } -const string TLSProperties::getCipherSuite() const -{ +const string TLSProperties::getCipherSuite() const { + return dynamicCast (m_data)->cipherSuite; } -TLSProperties_GnuTLS& TLSProperties_GnuTLS::operator=(const TLSProperties_GnuTLS& other) -{ +TLSProperties_GnuTLS& TLSProperties_GnuTLS::operator=(const TLSProperties_GnuTLS& other) { + cipherSuite = other.cipherSuite; return *this; diff --git a/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp index 2038778a..96bbaead 100644 --- a/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace net { namespace tls { -class TLSProperties_GnuTLS : public object -{ +class TLSProperties_GnuTLS : public object { + public: TLSProperties_GnuTLS& operator=(const TLSProperties_GnuTLS& other); diff --git a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp index dccfb5ec..8586537e 100644 --- a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -82,10 +82,10 @@ namespace tls { #ifndef VMIME_BUILDING_DOC // Initialize GNU TLS library -struct TLSGlobal -{ - TLSGlobal() - { +struct TLSGlobal { + + TLSGlobal() { + #if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) #if VMIME_GNUTLS_NEEDS_GCRYPT gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); @@ -104,8 +104,8 @@ struct TLSGlobal gnutls_certificate_allocate_credentials(&certCred); } - ~TLSGlobal() - { + ~TLSGlobal() { + gnutls_anon_free_client_credentials(anonCred); gnutls_certificate_free_credentials(certCred); @@ -114,8 +114,8 @@ struct TLSGlobal #if VMIME_DEBUG && GNUTLS_DEBUG - static void TLSLogFunc(int level, const char *str) - { + static void TLSLogFunc(int level, const char *str) { + std::cerr << "GNUTLS: [" << level << "] " << str << std::endl; } @@ -134,21 +134,29 @@ static TLSGlobal g_gnutlsGlobal; // static -shared_ptr TLSSession::create(const shared_ptr & cv, const shared_ptr & props) -{ +shared_ptr TLSSession::create( + const shared_ptr & cv, + const shared_ptr & props +) { + return make_shared (cv, props); } -TLSSession_GnuTLS::TLSSession_GnuTLS(const shared_ptr & cv, const shared_ptr & props) - : m_certVerifier(cv), m_props(props) -{ +TLSSession_GnuTLS::TLSSession_GnuTLS( + const shared_ptr & cv, + const shared_ptr & props +) + : m_certVerifier(cv), + m_props(props) { + int res; m_gnutlsSession = new gnutls_session_t; - if (gnutls_init(m_gnutlsSession, GNUTLS_CLIENT) != 0) + if (gnutls_init(m_gnutlsSession, GNUTLS_CLIENT) != 0) { throw std::bad_alloc(); + } // Sets some default priority on the ciphers, key exchange methods, // macs and compression methods. @@ -156,8 +164,8 @@ TLSSession_GnuTLS::TLSSession_GnuTLS(const shared_ptr getCipherSuite().c_str(), NULL)) != 0) - { + (*m_gnutlsSession, m_props->getCipherSuite().c_str(), NULL)) != 0) { + throwTLSException("gnutls_priority_set_direct", res); } @@ -170,13 +178,10 @@ TLSSession_GnuTLS::TLSSession_GnuTLS(const shared_ptr TLSSession_GnuTLS::getSocket(const shared_ptr & sok) -{ +shared_ptr TLSSession_GnuTLS::getSocket(const shared_ptr & sok) { + return TLSSocket::wrap(dynamicCast (shared_from_this()), sok); } -shared_ptr TLSSession_GnuTLS::getCertificateVerifier() -{ +shared_ptr TLSSession_GnuTLS::getCertificateVerifier() { + return m_certVerifier; } -void TLSSession_GnuTLS::throwTLSException(const string& fname, const int code) -{ +void TLSSession_GnuTLS::throwTLSException(const string& fname, const int code) { + std::ostringstream msg; msg << fname + "() returned code "; diff --git a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp index dd096ff3..2a7f9d7f 100644 --- a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,13 +46,17 @@ namespace net { namespace tls { -class TLSSession_GnuTLS : public TLSSession -{ +class TLSSession_GnuTLS : public TLSSession { + friend class TLSSocket_GnuTLS; public: - TLSSession_GnuTLS(const shared_ptr & cv, const shared_ptr & props); + TLSSession_GnuTLS( + const shared_ptr & cv, + const shared_ptr & props + ); + ~TLSSession_GnuTLS(); diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 31753590..93f1b763 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -50,17 +50,26 @@ namespace tls { // static -shared_ptr TLSSocket::wrap(const shared_ptr & session, const shared_ptr & sok) +shared_ptr TLSSocket::wrap( + const shared_ptr & session, + const shared_ptr & sok +) { - return make_shared - (dynamicCast (session), sok); + return make_shared (dynamicCast (session), sok); } -TLSSocket_GnuTLS::TLSSocket_GnuTLS(const shared_ptr & session, const shared_ptr & sok) - : m_session(session), m_wrapped(sok), m_connected(false), - m_ex(NULL), m_status(0), m_errno(0) -{ +TLSSocket_GnuTLS::TLSSocket_GnuTLS( + const shared_ptr & session, + const shared_ptr & sok +) + : m_session(session), + m_wrapped(sok), + m_connected(false), + m_ex(NULL), + m_status(0), + m_errno(0) { + gnutls_transport_set_ptr(*m_session->m_gnutlsSession, this); gnutls_transport_set_push_function(*m_session->m_gnutlsSession, gnutlsPushFunc); @@ -69,41 +78,38 @@ TLSSocket_GnuTLS::TLSSocket_GnuTLS(const shared_ptr & session } -TLSSocket_GnuTLS::~TLSSocket_GnuTLS() -{ +TLSSocket_GnuTLS::~TLSSocket_GnuTLS() { + resetException(); - try - { + try { disconnect(); - } - catch (...) - { + } catch (...) { // Don't throw exception in destructor } } -void TLSSocket_GnuTLS::connect(const string& address, const port_t port) -{ - try - { +void TLSSocket_GnuTLS::connect(const string& address, const port_t port) { + + try { + m_wrapped->connect(address, port); handshake(); - } - catch (...) - { + + } catch (...) { + disconnect(); throw; } } -void TLSSocket_GnuTLS::disconnect() -{ - if (m_connected) - { +void TLSSocket_GnuTLS::disconnect() { + + if (m_connected) { + gnutls_bye(*m_session->m_gnutlsSession, GNUTLS_SHUT_RDWR); m_wrapped->disconnect(); @@ -113,99 +119,101 @@ void TLSSocket_GnuTLS::disconnect() } -bool TLSSocket_GnuTLS::isConnected() const -{ +bool TLSSocket_GnuTLS::isConnected() const { + return m_wrapped->isConnected() && m_connected; } -size_t TLSSocket_GnuTLS::getBlockSize() const -{ +size_t TLSSocket_GnuTLS::getBlockSize() const { + return 16384; // 16 KB } -const string TLSSocket_GnuTLS::getPeerName() const -{ +const string TLSSocket_GnuTLS::getPeerName() const { + return m_wrapped->getPeerName(); } -const string TLSSocket_GnuTLS::getPeerAddress() const -{ +const string TLSSocket_GnuTLS::getPeerAddress() const { + return m_wrapped->getPeerAddress(); } -shared_ptr TLSSocket_GnuTLS::getTimeoutHandler() -{ +shared_ptr TLSSocket_GnuTLS::getTimeoutHandler() { + return m_wrapped->getTimeoutHandler(); } -void TLSSocket_GnuTLS::setTracer(const shared_ptr & tracer) -{ +void TLSSocket_GnuTLS::setTracer(const shared_ptr & tracer) { + m_wrapped->setTracer(tracer); } -shared_ptr TLSSocket_GnuTLS::getTracer() -{ +shared_ptr TLSSocket_GnuTLS::getTracer() { + return m_wrapped->getTracer(); } -bool TLSSocket_GnuTLS::waitForRead(const int msecs) -{ +bool TLSSocket_GnuTLS::waitForRead(const int msecs) { + return m_wrapped->waitForRead(msecs); } -bool TLSSocket_GnuTLS::waitForWrite(const int msecs) -{ +bool TLSSocket_GnuTLS::waitForWrite(const int msecs) { + return m_wrapped->waitForWrite(msecs); } -void TLSSocket_GnuTLS::receive(string& buffer) -{ +void TLSSocket_GnuTLS::receive(string& buffer) { + const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size); } -void TLSSocket_GnuTLS::send(const string& buffer) -{ +void TLSSocket_GnuTLS::send(const string& buffer) { + sendRaw(reinterpret_cast (buffer.data()), buffer.length()); } -void TLSSocket_GnuTLS::send(const char* str) -{ +void TLSSocket_GnuTLS::send(const char* str) { + sendRaw(reinterpret_cast (str), ::strlen(str)); } -size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count) -{ +size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count) { + m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); resetException(); - const ssize_t ret = gnutls_record_recv - (*m_session->m_gnutlsSession, - buffer, static_cast (count)); + const ssize_t ret = gnutls_record_recv( + *m_session->m_gnutlsSession, + buffer, static_cast (count) + ); throwException(); - if (ret < 0) - { - if (ret == GNUTLS_E_AGAIN) - { - if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) + if (ret < 0) { + + if (ret == GNUTLS_E_AGAIN) { + + if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) { m_status |= STATUS_WANT_READ; - else + } else { m_status |= STATUS_WANT_WRITE; + } return 0; } @@ -217,36 +225,38 @@ size_t TLSSocket_GnuTLS::receiveRaw(byte_t* buffer, const size_t count) } -void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count) -{ +void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count) { + m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); - for (size_t size = count ; size > 0 ; ) - { + for (size_t size = count ; size > 0 ; ) { + resetException(); - ssize_t ret = gnutls_record_send - (*m_session->m_gnutlsSession, - buffer, static_cast (size)); + ssize_t ret = gnutls_record_send( + *m_session->m_gnutlsSession, + buffer, static_cast (size) + ); throwException(); - if (ret < 0) - { - if (ret == GNUTLS_E_AGAIN) - { - if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) + if (ret < 0) { + + if (ret == GNUTLS_E_AGAIN) { + + if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) { m_wrapped->waitForRead(); - else + } else { m_wrapped->waitForWrite(); + } continue; } TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast (ret)); - } - else - { + + } else { + buffer += ret; size -= ret; } @@ -254,26 +264,28 @@ void TLSSocket_GnuTLS::sendRaw(const byte_t* buffer, const size_t count) } -size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t count) -{ +size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t count) { + m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); resetException(); - ssize_t ret = gnutls_record_send - (*m_session->m_gnutlsSession, - buffer, static_cast (count)); + ssize_t ret = gnutls_record_send( + *m_session->m_gnutlsSession, + buffer, static_cast (count) + ); throwException(); - if (ret < 0) - { - if (ret == GNUTLS_E_AGAIN) - { - if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) + if (ret < 0) { + + if (ret == GNUTLS_E_AGAIN) { + + if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) { m_status |= STATUS_WANT_READ; - else + } else { m_status |= STATUS_WANT_WRITE; + } return 0; } @@ -285,68 +297,72 @@ size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t c } -unsigned int TLSSocket_GnuTLS::getStatus() const -{ +unsigned int TLSSocket_GnuTLS::getStatus() const { + return m_status | m_wrapped->getStatus(); } -void TLSSocket_GnuTLS::handshake() -{ +void TLSSocket_GnuTLS::handshake() { + shared_ptr toHandler = m_wrapped->getTimeoutHandler(); - if (toHandler) + if (toHandler) { toHandler->resetTimeOut(); + } - if (getTracer()) + if (getTracer()) { getTracer()->traceSend("Beginning SSL/TLS handshake"); + } // Start handshaking process - try - { - while (true) - { + try { + + while (true) { + resetException(); const int ret = gnutls_handshake(*m_session->m_gnutlsSession); throwException(); - if (ret < 0) - { - if (ret == GNUTLS_E_AGAIN) - { - if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) + if (ret < 0) { + + if (ret == GNUTLS_E_AGAIN) { + + if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) { m_wrapped->waitForRead(); - else + } else { m_wrapped->waitForWrite(); - } - else if (ret == GNUTLS_E_INTERRUPTED) - { + } + + } else if (ret == GNUTLS_E_INTERRUPTED) { + // Non-fatal error - } - else - { + + } else { + TLSSession_GnuTLS::throwTLSException("gnutls_handshake", ret); } - } - else - { + + } else { + // Successful handshake break; } } - } - catch (...) - { + + } catch (...) { + throw; } // Verify server's certificate(s) shared_ptr certs = getPeerCertificates(); - if (certs == NULL) + if (certs == NULL) { throw exceptions::tls_exception("No peer certificate."); + } m_session->getCertificateVerifier()->verify(certs, getPeerName()); @@ -354,35 +370,38 @@ void TLSSocket_GnuTLS::handshake() } -int TLSSocket_GnuTLS::gnutlsErrnoFunc(gnutls_transport_ptr_t trspt) -{ +int TLSSocket_GnuTLS::gnutlsErrnoFunc(gnutls_transport_ptr_t trspt) { + TLSSocket_GnuTLS* sok = reinterpret_cast (trspt); return sok->m_errno; } -ssize_t TLSSocket_GnuTLS::gnutlsPushFunc - (gnutls_transport_ptr_t trspt, const void* data, size_t len) -{ +ssize_t TLSSocket_GnuTLS::gnutlsPushFunc( + gnutls_transport_ptr_t trspt, + const void* data, + size_t len +) { + TLSSocket_GnuTLS* sok = reinterpret_cast (trspt); - try - { - const ssize_t ret = static_cast - (sok->m_wrapped->sendRawNonBlocking - (reinterpret_cast (data), len)); + try { + + const ssize_t ret = static_cast ( + sok->m_wrapped->sendRawNonBlocking(reinterpret_cast (data), len) + ); + + if (ret == 0) { - if (ret == 0) - { gnutls_transport_set_errno(*sok->m_session->m_gnutlsSession, EAGAIN); sok->m_errno = EAGAIN; return -1; } return ret; - } - catch (exception& e) - { + + } catch (exception& e) { + // Workaround for non-portable behaviour when throwing C++ exceptions // from C functions (GNU TLS) sok->m_ex = e.clone(); @@ -391,28 +410,31 @@ ssize_t TLSSocket_GnuTLS::gnutlsPushFunc } -ssize_t TLSSocket_GnuTLS::gnutlsPullFunc - (gnutls_transport_ptr_t trspt, void* data, size_t len) -{ +ssize_t TLSSocket_GnuTLS::gnutlsPullFunc( + gnutls_transport_ptr_t trspt, + void* data, + size_t len +) { + TLSSocket_GnuTLS* sok = reinterpret_cast (trspt); - try - { - const ssize_t n = static_cast - (sok->m_wrapped->receiveRaw - (reinterpret_cast (data), len)); + try { + + const ssize_t n = static_cast ( + sok->m_wrapped->receiveRaw(reinterpret_cast (data), len) + ); + + if (n == 0) { - if (n == 0) - { gnutls_transport_set_errno(*sok->m_session->m_gnutlsSession, EAGAIN); sok->m_errno = EAGAIN; return -1; } return n; - } - catch (exception& e) - { + + } catch (exception& e) { + // Workaround for non-portable behaviour when throwing C++ exceptions // from C functions (GNU TLS) sok->m_ex = e.clone(); @@ -421,74 +443,69 @@ ssize_t TLSSocket_GnuTLS::gnutlsPullFunc } -shared_ptr TLSSocket_GnuTLS::getPeerCertificates() -{ - if (getTracer()) +shared_ptr TLSSocket_GnuTLS::getPeerCertificates() { + + if (getTracer()) { getTracer()->traceSend("Getting peer certificates"); + } unsigned int certCount = 0; - const gnutls_datum_t* rawData = gnutls_certificate_get_peers - (*m_session->m_gnutlsSession, &certCount); + const gnutls_datum_t* rawData = gnutls_certificate_get_peers( + *m_session->m_gnutlsSession, &certCount + ); - if (rawData == NULL) + if (rawData == NULL) { return null; + } // Try X.509 gnutls_x509_crt_t* x509Certs = new gnutls_x509_crt_t[certCount]; - for (unsigned int i = 0; i < certCount; ++i) - { + for (unsigned int i = 0; i < certCount; ++i) { + gnutls_x509_crt_init(x509Certs + i); - int res = gnutls_x509_crt_import(x509Certs[i], rawData + i, - GNUTLS_X509_FMT_DER); + int res = gnutls_x509_crt_import(x509Certs[i], rawData + i, GNUTLS_X509_FMT_DER); - if (res < 0) - { + if (res < 0) { // XXX more fine-grained error reporting? delete [] x509Certs; return null; } } - { - std::vector > certs; - bool error = false; + std::vector > certs; + bool error = false; - for (unsigned int i = 0 ; i < certCount ; ++i) - { - size_t dataSize = 0; + for (unsigned int i = 0 ; i < certCount ; ++i) { - gnutls_x509_crt_export(x509Certs[i], - GNUTLS_X509_FMT_DER, NULL, &dataSize); + size_t dataSize = 0; - std::vector data(dataSize); + gnutls_x509_crt_export(x509Certs[i], GNUTLS_X509_FMT_DER, NULL, &dataSize); - gnutls_x509_crt_export(x509Certs[i], - GNUTLS_X509_FMT_DER, &data[0], &dataSize); + std::vector data(dataSize); - shared_ptr cert = - security::cert::X509Certificate::import(&data[0], dataSize); + gnutls_x509_crt_export(x509Certs[i], GNUTLS_X509_FMT_DER, &data[0], &dataSize); - if (cert != NULL) - certs.push_back(cert); - else - error = true; + shared_ptr cert = + security::cert::X509Certificate::import(&data[0], dataSize); - gnutls_x509_crt_deinit(x509Certs[i]); + if (cert != NULL) { + certs.push_back(cert); + } else { + error = true; } - delete [] x509Certs; - - if (error) - return null; - - return make_shared (certs); + gnutls_x509_crt_deinit(x509Certs[i]); } delete [] x509Certs; - return null; + if (error) { + return null; + } + + return make_shared (certs); } @@ -498,19 +515,17 @@ shared_ptr TLSSocket_GnuTLS::getPeerCertifica // gnutls_record_recv() calls TLSSocket::gnutlsPullFunc, and exceptions // thrown by the socket can not be caught. -void TLSSocket_GnuTLS::throwException() -{ - if (m_ex) - { +void TLSSocket_GnuTLS::throwException() { + + if (m_ex) { throw *m_ex; } } -void TLSSocket_GnuTLS::resetException() -{ - if (m_ex) - { +void TLSSocket_GnuTLS::resetException() { + + if (m_ex) { delete m_ex; m_ex = NULL; } diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp index a1d78e99..0ac3e700 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,8 +46,8 @@ class TLSSession; class TLSSession_GnuTLS; -class TLSSocket_GnuTLS : public TLSSocket -{ +class TLSSocket_GnuTLS : public TLSSocket { + public: TLSSocket_GnuTLS(const shared_ptr & session, const shared_ptr & sok); diff --git a/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp b/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp index 1bbb9ee5..74474480 100644 --- a/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp +++ b/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,34 +52,34 @@ namespace tls { shared_ptr * OpenSSLInitializer::sm_mutexes; -OpenSSLInitializer::autoInitializer::autoInitializer() -{ +OpenSSLInitializer::autoInitializer::autoInitializer() { + // The construction of this unique 'oneTimeInitializer' object will be triggered // by the 'autoInitializer' objects from the other translation units static OpenSSLInitializer::oneTimeInitializer oneTimeInitializer; } -OpenSSLInitializer::autoInitializer::~autoInitializer() -{ +OpenSSLInitializer::autoInitializer::~autoInitializer() { + } -OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer() -{ +OpenSSLInitializer::oneTimeInitializer::oneTimeInitializer() { + initialize(); } -OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer() -{ +OpenSSLInitializer::oneTimeInitializer::~oneTimeInitializer() { + uninitialize(); } // static -void OpenSSLInitializer::initialize() -{ +void OpenSSLInitializer::initialize() { + #if OPENSSL_VERSION_NUMBER >= 0x0907000L OPENSSL_config(NULL); #endif @@ -95,8 +95,9 @@ void OpenSSLInitializer::initialize() int numMutexes = CRYPTO_num_locks(); sm_mutexes = new shared_ptr [numMutexes]; - for (int i = 0 ; i < numMutexes ; ++i) + for (int i = 0 ; i < numMutexes ; ++i) { sm_mutexes[i] = vmime::platform::getHandler()->createCriticalSection(); + } CRYPTO_set_locking_callback(&OpenSSLInitializer::lock); CRYPTO_set_id_callback(&OpenSSLInitializer::id); @@ -104,8 +105,8 @@ void OpenSSLInitializer::initialize() // static -void OpenSSLInitializer::uninitialize() -{ +void OpenSSLInitializer::uninitialize() { + EVP_cleanup(); ERR_free_strings(); @@ -117,18 +118,19 @@ void OpenSSLInitializer::uninitialize() // static -void OpenSSLInitializer::lock(int mode, int n, const char* /* file */, int /* line */) -{ - if (mode & CRYPTO_LOCK) +void OpenSSLInitializer::lock(int mode, int n, const char* /* file */, int /* line */) { + + if (mode & CRYPTO_LOCK) { sm_mutexes[n]->lock(); - else + } else { sm_mutexes[n]->unlock(); + } } // static -unsigned long OpenSSLInitializer::id() -{ +unsigned long OpenSSLInitializer::id() { + return vmime::platform::getHandler()->getThreadId(); } diff --git a/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp b/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp index d7595aa8..b07c2e61 100644 --- a/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp +++ b/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,15 +46,13 @@ namespace tls { /** Class responsible for setting up OpenSSL */ -class OpenSSLInitializer -{ +class OpenSSLInitializer { + public: /** Automatically initialize OpenSSL */ - class autoInitializer - { - public: + struct autoInitializer { autoInitializer(); ~autoInitializer(); @@ -62,9 +60,7 @@ public: protected: - class oneTimeInitializer - { - public: + struct oneTimeInitializer { oneTimeInitializer(); ~oneTimeInitializer(); @@ -82,8 +78,7 @@ protected: static shared_ptr getMutex(); - enum - { + enum { SEEDSIZE = 256 }; diff --git a/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp index 932477df..ea22f1cd 100644 --- a/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,63 +40,63 @@ namespace tls { TLSProperties::TLSProperties() - : m_data(make_shared ()) -{ + : m_data(make_shared ()) { + setCipherSuite(CIPHERSUITE_DEFAULT); } TLSProperties::TLSProperties(const TLSProperties& props) : object(), - m_data(make_shared ()) -{ + m_data(make_shared ()) { + *dynamicCast (m_data) = *dynamicCast (props.m_data); } -void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite) -{ - switch (cipherSuite) - { - case CIPHERSUITE_HIGH: +void TLSProperties::setCipherSuite(const GenericCipherSuite cipherSuite) { - setCipherSuite("HIGH:!ADH:@STRENGTH"); - break; + switch (cipherSuite) { - case CIPHERSUITE_MEDIUM: + case CIPHERSUITE_HIGH: - setCipherSuite("MEDIUM:!ADH:@STRENGTH"); - break; + setCipherSuite("HIGH:!ADH:@STRENGTH"); + break; - case CIPHERSUITE_LOW: + case CIPHERSUITE_MEDIUM: - setCipherSuite("LOW:!ADH:@STRENGTH"); - break; + setCipherSuite("MEDIUM:!ADH:@STRENGTH"); + break; - default: - case CIPHERSUITE_DEFAULT: + case CIPHERSUITE_LOW: - setCipherSuite("DEFAULT:!ADH:@STRENGTH"); - break; + setCipherSuite("LOW:!ADH:@STRENGTH"); + break; + + default: + case CIPHERSUITE_DEFAULT: + + setCipherSuite("DEFAULT:!ADH:@STRENGTH"); + break; } } -void TLSProperties::setCipherSuite(const string& cipherSuite) -{ +void TLSProperties::setCipherSuite(const string& cipherSuite) { + dynamicCast (m_data)->cipherSuite = cipherSuite; } -const string TLSProperties::getCipherSuite() const -{ +const string TLSProperties::getCipherSuite() const { + return dynamicCast (m_data)->cipherSuite; } -TLSProperties_OpenSSL& TLSProperties_OpenSSL::operator=(const TLSProperties_OpenSSL& other) -{ +TLSProperties_OpenSSL& TLSProperties_OpenSSL::operator=(const TLSProperties_OpenSSL& other) { + cipherSuite = other.cipherSuite; return *this; diff --git a/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp index 5d2f075a..8304df23 100644 --- a/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp +++ b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace net { namespace tls { -class TLSProperties_OpenSSL : public object -{ +class TLSProperties_OpenSSL : public object { + public: TLSProperties_OpenSSL& operator=(const TLSProperties_OpenSSL& other); diff --git a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp index 961f6517..019341c7 100644 --- a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,15 +46,23 @@ static OpenSSLInitializer::autoInitializer openSSLInitializer; // static -shared_ptr TLSSession::create(const shared_ptr & cv, const shared_ptr & props) -{ +shared_ptr TLSSession::create( + const shared_ptr & cv, + const shared_ptr & props +) { + return make_shared (cv, props); } -TLSSession_OpenSSL::TLSSession_OpenSSL(const shared_ptr & cv, const shared_ptr & props) - : m_sslctx(0), m_certVerifier(cv), m_props(props) -{ +TLSSession_OpenSSL::TLSSession_OpenSSL( + const shared_ptr & cv, + const shared_ptr & props +) + : m_sslctx(0), + m_certVerifier(cv), + m_props(props) { + m_sslctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_options(m_sslctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); SSL_CTX_set_mode(m_sslctx, SSL_MODE_AUTO_RETRY); @@ -64,36 +72,36 @@ TLSSession_OpenSSL::TLSSession_OpenSSL(const shared_ptr TLSSession_OpenSSL::getSocket(const shared_ptr & sok) -{ +shared_ptr TLSSession_OpenSSL::getSocket(const shared_ptr & sok) { + return TLSSocket::wrap(dynamicCast (shared_from_this()), sok); } -shared_ptr TLSSession_OpenSSL::getCertificateVerifier() -{ +shared_ptr TLSSession_OpenSSL::getCertificateVerifier() { + return m_certVerifier; } -void TLSSession_OpenSSL::usePrivateKeyFile(const vmime::string& keyfile) -{ +void TLSSession_OpenSSL::usePrivateKeyFile(const vmime::string& keyfile) { + ERR_clear_error(); - if (SSL_CTX_use_PrivateKey_file(m_sslctx, keyfile.c_str(), SSL_FILETYPE_PEM) != 1) - { + if (SSL_CTX_use_PrivateKey_file(m_sslctx, keyfile.c_str(), SSL_FILETYPE_PEM) != 1) { + unsigned long errCode = ERR_get_error(); char buffer[256]; ERR_error_string_n(errCode, buffer, sizeof(buffer)); @@ -106,12 +114,12 @@ void TLSSession_OpenSSL::usePrivateKeyFile(const vmime::string& keyfile) } -void TLSSession_OpenSSL::useCertificateChainFile(const vmime::string& chainFile) -{ +void TLSSession_OpenSSL::useCertificateChainFile(const vmime::string& chainFile) { + ERR_clear_error(); - if (SSL_CTX_use_certificate_chain_file(m_sslctx, chainFile.c_str()) != 1) - { + if (SSL_CTX_use_certificate_chain_file(m_sslctx, chainFile.c_str()) != 1) { + unsigned long errCode = ERR_get_error(); char buffer[256]; ERR_error_string_n(errCode, buffer, sizeof(buffer)); @@ -124,8 +132,8 @@ void TLSSession_OpenSSL::useCertificateChainFile(const vmime::string& chainFile) } -SSL_CTX* TLSSession_OpenSSL::getContext() const -{ +SSL_CTX* TLSSession_OpenSSL::getContext() const { + return m_sslctx; } diff --git a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp index c5c5da39..518216bc 100644 --- a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,13 +49,17 @@ namespace net { namespace tls { -class TLSSession_OpenSSL : public TLSSession -{ +class TLSSession_OpenSSL : public TLSSession { + friend class TLSSocket_OpenSSL; public: - TLSSession_OpenSSL(const shared_ptr & cv, const shared_ptr & props); + TLSSession_OpenSSL( + const shared_ptr & cv, + const shared_ptr & props + ); + ~TLSSession_OpenSSL(); @@ -66,13 +70,11 @@ public: /** Set the private key to use if server requires a client certificate. * - * @param keyfile Path to the private key in PEM format - * @param passwd_callback If the private key is stored encrypted the + * @param keyfile path to the private key in PEM format */ void usePrivateKeyFile(const vmime::string& keyfile); - /** Supply the certificate chain to present if requested by - * server. + /** Supply the certificate chain to present if requested by server. * * @param chainFile File in PEM format holding certificate chain */ @@ -105,4 +107,3 @@ private: #endif // VMIME_BUILDING_DOC #endif // VMIME_NET_TLS_TLSSESSION_OPENSSL_HPP_INCLUDED - diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp index afc7e514..db782bb2 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -55,8 +55,7 @@ static OpenSSLInitializer::autoInitializer openSSLInitializer; #if OPENSSL_VERSION_NUMBER < 0x10100000L // static -BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = -{ +BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = { 100 | BIO_TYPE_SOURCE_SINK, "vmime::socket glue", TLSSocket_OpenSSL::bio_write, @@ -87,36 +86,42 @@ BIO_METHOD TLSSocket_OpenSSL::sm_customBIOMethod = // static -shared_ptr TLSSocket::wrap(const shared_ptr & session, const shared_ptr & sok) -{ - return make_shared - (dynamicCast (session), sok); +shared_ptr TLSSocket::wrap( + const shared_ptr & session, + const shared_ptr & sok +) { + + return make_shared (dynamicCast (session), sok); } -TLSSocket_OpenSSL::TLSSocket_OpenSSL(const shared_ptr & session, const shared_ptr & sok) - : m_session(session), m_wrapped(sok), m_connected(false), m_ssl(0), m_status(0), m_ex() -{ +TLSSocket_OpenSSL::TLSSocket_OpenSSL( + const shared_ptr & session, + const shared_ptr & sok +) + : m_session(session), + m_wrapped(sok), + m_connected(false), + m_ssl(0), + m_status(0), + m_ex() { + } -TLSSocket_OpenSSL::~TLSSocket_OpenSSL() -{ - try - { +TLSSocket_OpenSSL::~TLSSocket_OpenSSL() { + + try { disconnect(); - } - catch (...) - { + } catch (...) { // Don't throw in destructor } } -void TLSSocket_OpenSSL::createSSLHandle() -{ - if (m_wrapped->isConnected()) - { +void TLSSocket_OpenSSL::createSSLHandle() { + + if (m_wrapped->isConnected()) { #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -128,8 +133,7 @@ void TLSSocket_OpenSSL::createSSLHandle() BIO_METHOD* bioMeth = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "vmime::socket glue"); - if (!bioMeth) - { + if (!bioMeth) { BIO_meth_free(bioMeth); throw exceptions::tls_exception("BIO_meth_new() failed"); } @@ -147,15 +151,13 @@ void TLSSocket_OpenSSL::createSSLHandle() #endif - if (!sockBio) - { + if (!sockBio) { throw exceptions::tls_exception("BIO_new() failed"); } m_ssl = SSL_new(m_session->getContext()); - if (!m_ssl) - { + if (!m_ssl) { BIO_free(sockBio); throw exceptions::tls_exception("Cannot create SSL object"); } @@ -163,156 +165,156 @@ void TLSSocket_OpenSSL::createSSLHandle() SSL_set_bio(m_ssl, sockBio, sockBio); SSL_set_connect_state(m_ssl); SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - } - else - { + + } else { + throw exceptions::tls_exception("Unconnected socket error"); } } -void TLSSocket_OpenSSL::connect(const string& address, const port_t port) -{ - try - { +void TLSSocket_OpenSSL::connect(const string& address, const port_t port) { + + try { + m_wrapped->connect(address, port); createSSLHandle(); handshake(); - } - catch (...) - { + + } catch (...) { + disconnect(); throw; } } -void TLSSocket_OpenSSL::disconnect() -{ - if (m_ssl) - { +void TLSSocket_OpenSSL::disconnect() { + + if (m_ssl) { + // Don't shut down the socket more than once. int shutdownState = SSL_get_shutdown(m_ssl); bool shutdownSent = (shutdownState & SSL_SENT_SHUTDOWN) == SSL_SENT_SHUTDOWN; - if (!shutdownSent) + if (!shutdownSent) { SSL_shutdown(m_ssl); + } SSL_free(m_ssl); m_ssl = 0; } - if (m_connected) - { + if (m_connected) { m_connected = false; m_wrapped->disconnect(); } } -bool TLSSocket_OpenSSL::isConnected() const -{ +bool TLSSocket_OpenSSL::isConnected() const { + return m_wrapped->isConnected() && m_connected; } -size_t TLSSocket_OpenSSL::getBlockSize() const -{ +size_t TLSSocket_OpenSSL::getBlockSize() const { + return 16384; // 16 KB } -const string TLSSocket_OpenSSL::getPeerName() const -{ +const string TLSSocket_OpenSSL::getPeerName() const { + return m_wrapped->getPeerName(); } -const string TLSSocket_OpenSSL::getPeerAddress() const -{ +const string TLSSocket_OpenSSL::getPeerAddress() const { + return m_wrapped->getPeerAddress(); } -shared_ptr TLSSocket_OpenSSL::getTimeoutHandler() -{ +shared_ptr TLSSocket_OpenSSL::getTimeoutHandler() { + return m_wrapped->getTimeoutHandler(); } -void TLSSocket_OpenSSL::setTracer(const shared_ptr & tracer) -{ +void TLSSocket_OpenSSL::setTracer(const shared_ptr & tracer) { + m_wrapped->setTracer(tracer); } -shared_ptr TLSSocket_OpenSSL::getTracer() -{ +shared_ptr TLSSocket_OpenSSL::getTracer() { + return m_wrapped->getTracer(); } -bool TLSSocket_OpenSSL::waitForRead(const int msecs) -{ +bool TLSSocket_OpenSSL::waitForRead(const int msecs) { + return m_wrapped->waitForRead(msecs); } -bool TLSSocket_OpenSSL::waitForWrite(const int msecs) -{ +bool TLSSocket_OpenSSL::waitForWrite(const int msecs) { + return m_wrapped->waitForWrite(msecs); } -void TLSSocket_OpenSSL::receive(string& buffer) -{ +void TLSSocket_OpenSSL::receive(string& buffer) { + const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); - if (size != 0) + if (size != 0) { buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size); - else + } else { buffer.clear(); + } } -void TLSSocket_OpenSSL::send(const string& buffer) -{ +void TLSSocket_OpenSSL::send(const string& buffer) { + sendRaw(reinterpret_cast (buffer.data()), buffer.length()); } -void TLSSocket_OpenSSL::send(const char* str) -{ +void TLSSocket_OpenSSL::send(const char* str) { + sendRaw(reinterpret_cast (str), ::strlen(str)); } -size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count) -{ - if (!m_ssl) +size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count) { + + if (!m_ssl) { throw exceptions::socket_not_connected_exception(); + } m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); ERR_clear_error(); int rc = SSL_read(m_ssl, buffer, static_cast (count)); - if (m_ex.get()) + if (m_ex.get()) { internalThrow(); + } + + if (rc <= 0) { - if (rc <= 0) - { int error = SSL_get_error(m_ssl, rc); - if (error == SSL_ERROR_WANT_WRITE) - { + if (error == SSL_ERROR_WANT_WRITE) { m_status |= STATUS_WANT_WRITE; return 0; - } - else if (error == SSL_ERROR_WANT_READ) - { + } else if (error == SSL_ERROR_WANT_READ) { m_status |= STATUS_WANT_READ; return 0; } @@ -324,37 +326,35 @@ size_t TLSSocket_OpenSSL::receiveRaw(byte_t* buffer, const size_t count) } -void TLSSocket_OpenSSL::sendRaw(const byte_t* buffer, const size_t count) -{ - if (!m_ssl) +void TLSSocket_OpenSSL::sendRaw(const byte_t* buffer, const size_t count) { + + if (!m_ssl) { throw exceptions::socket_not_connected_exception(); + } m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); - for (size_t size = count ; size > 0 ; ) - { + for (size_t size = count ; size > 0 ; ) { + ERR_clear_error(); int rc = SSL_write(m_ssl, buffer, static_cast (size)); - if (rc <= 0) - { + if (rc <= 0) { + int error = SSL_get_error(m_ssl, rc); - if (error == SSL_ERROR_WANT_READ) - { + if (error == SSL_ERROR_WANT_READ) { m_wrapped->waitForRead(); continue; - } - else if (error == SSL_ERROR_WANT_WRITE) - { + } else if (error == SSL_ERROR_WANT_WRITE) { m_wrapped->waitForWrite(); continue; } handleError(rc); - } - else - { + + } else { + buffer += rc; size -= rc; } @@ -362,30 +362,29 @@ void TLSSocket_OpenSSL::sendRaw(const byte_t* buffer, const size_t count) } -size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t count) -{ - if (!m_ssl) +size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t count) { + + if (!m_ssl) { throw exceptions::socket_not_connected_exception(); + } m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ); ERR_clear_error(); int rc = SSL_write(m_ssl, buffer, static_cast (count)); - if (m_ex.get()) + if (m_ex.get()) { internalThrow(); + } + + if (rc <= 0) { - if (rc <= 0) - { int error = SSL_get_error(m_ssl, rc); - if (error == SSL_ERROR_WANT_WRITE) - { + if (error == SSL_ERROR_WANT_WRITE) { m_status |= STATUS_WANT_WRITE; return 0; - } - else if (error == SSL_ERROR_WANT_READ) - { + } else if (error == SSL_ERROR_WANT_READ) { m_status |= STATUS_WANT_READ; return 0; } @@ -397,59 +396,65 @@ size_t TLSSocket_OpenSSL::sendRawNonBlocking(const byte_t* buffer, const size_t } -void TLSSocket_OpenSSL::handshake() -{ +void TLSSocket_OpenSSL::handshake() { + shared_ptr toHandler = m_wrapped->getTimeoutHandler(); - if (toHandler) + if (toHandler) { toHandler->resetTimeOut(); + } - if (getTracer()) + if (getTracer()) { getTracer()->traceSend("Beginning SSL/TLS handshake"); + } // Start handshaking process - if (!m_ssl) + if (!m_ssl) { createSSLHandle(); + } + + try { - try - { int rc; ERR_clear_error(); - while ((rc = SSL_do_handshake(m_ssl)) <= 0) - { + while ((rc = SSL_do_handshake(m_ssl)) <= 0) { + const int err = SSL_get_error(m_ssl, rc); - if (err == SSL_ERROR_WANT_READ) + if (err == SSL_ERROR_WANT_READ) { m_wrapped->waitForRead(); - else if (err == SSL_ERROR_WANT_WRITE) + } else if (err == SSL_ERROR_WANT_WRITE) { m_wrapped->waitForWrite(); - else + } else { handleError(rc); + } // Check whether the time-out delay is elapsed - if (toHandler && toHandler->isTimeOut()) - { - if (!toHandler->handleTimeOut()) + if (toHandler && toHandler->isTimeOut()) { + + if (!toHandler->handleTimeOut()) { throw exceptions::operation_timed_out(); + } toHandler->resetTimeOut(); } ERR_clear_error(); } - } - catch (...) - { + + } catch (...) { + throw; } // Verify server's certificate(s) shared_ptr certs = getPeerCertificates(); - if (certs == NULL) + if (!certs) { throw exceptions::tls_exception("No peer certificate."); + } m_session->getCertificateVerifier()->verify(certs, getPeerName()); @@ -457,121 +462,130 @@ void TLSSocket_OpenSSL::handshake() } -shared_ptr TLSSocket_OpenSSL::getPeerCertificates() -{ - if (getTracer()) +shared_ptr TLSSocket_OpenSSL::getPeerCertificates() { + + if (getTracer()) { getTracer()->traceSend("Getting peer certificates"); + } STACK_OF(X509)* chain = SSL_get_peer_cert_chain(m_ssl); - if (chain == NULL) + if (chain == NULL) { return null; + } int certCount = sk_X509_num(chain); - if (certCount == 0) + if (certCount == 0) { return null; + } bool error = false; std::vector > certs; - for (int i = 0; i < certCount && !error; i++) - { + for (int i = 0; i < certCount && !error; i++) { + shared_ptr cert = vmime::security::cert::X509Certificate_OpenSSL::importInternal(sk_X509_value(chain, i)); - if (cert) + if (cert) { certs.push_back(cert); - else + } else { error = true; + } } - if (error) + if (error) { return null; + } return make_shared (certs); } -void TLSSocket_OpenSSL::internalThrow() -{ - if (m_ex.get()) +void TLSSocket_OpenSSL::internalThrow() { + + if (m_ex.get()) { throw *m_ex; + } } -void TLSSocket_OpenSSL::handleError(int rc) -{ - if (rc > 0) return; +void TLSSocket_OpenSSL::handleError(int rc) { + + if (rc > 0) { + return; + } internalThrow(); int sslError = SSL_get_error(m_ssl, rc); long lastError = ERR_get_error(); - switch (sslError) - { - case SSL_ERROR_ZERO_RETURN: + switch (sslError) { - disconnect(); - return; + case SSL_ERROR_ZERO_RETURN: - case SSL_ERROR_SYSCALL: - { - if (lastError == 0) - { - if (rc == 0) - { - throw exceptions::tls_exception("SSL connection unexpectedly closed"); + disconnect(); + return; + + case SSL_ERROR_SYSCALL: { + + if (lastError == 0) { + + if (rc == 0) { + + throw exceptions::tls_exception("SSL connection unexpectedly closed"); + + } else { + + std::ostringstream oss; + oss << "The BIO reported an error: " << rc; + oss.flush(); + throw exceptions::tls_exception(oss.str()); + } } - else - { - std::ostringstream oss; - oss << "The BIO reported an error: " << rc; - oss.flush(); - throw exceptions::tls_exception(oss.str()); + + break; + } + + case SSL_ERROR_WANT_READ: + + BIO_set_retry_read(SSL_get_rbio(m_ssl)); + break; + + case SSL_ERROR_WANT_WRITE: + + BIO_set_retry_write(SSL_get_wbio(m_ssl)); + break; + + // This happens only for BIOs of type BIO_s_connect() or BIO_s_accept() + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + // SSL_CTX_set_client_cert_cb related, not used + case SSL_ERROR_WANT_X509_LOOKUP: + case SSL_ERROR_SSL: + default: + + if (lastError == 0) { + + throw exceptions::tls_exception("Unexpected SSL IO error"); + + } else { + + char buffer[256]; + ERR_error_string_n(lastError, buffer, sizeof(buffer)); + vmime::string msg(buffer); + throw exceptions::tls_exception(msg); } - } - break; - } - case SSL_ERROR_WANT_READ: - - BIO_set_retry_read(SSL_get_rbio(m_ssl)); - break; - - case SSL_ERROR_WANT_WRITE: - - BIO_set_retry_write(SSL_get_wbio(m_ssl)); - break; - - // This happens only for BIOs of type BIO_s_connect() or BIO_s_accept() - case SSL_ERROR_WANT_CONNECT: - case SSL_ERROR_WANT_ACCEPT: - // SSL_CTX_set_client_cert_cb related, not used - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - default: - - if (lastError == 0) - { - throw exceptions::tls_exception("Unexpected SSL IO error"); - } - else - { - char buffer[256]; - ERR_error_string_n(lastError, buffer, sizeof(buffer)); - vmime::string msg(buffer); - throw exceptions::tls_exception(msg); - } - - break; + break; } } -unsigned int TLSSocket_OpenSSL::getStatus() const -{ +unsigned int TLSSocket_OpenSSL::getStatus() const { + return m_status; } @@ -580,33 +594,35 @@ unsigned int TLSSocket_OpenSSL::getStatus() const // static -int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len) -{ +int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len) { + BIO_clear_retry_flags(bio); - if (buf == NULL || len <= 0) + if (buf == NULL || len <= 0) { return -1; + } TLSSocket_OpenSSL *sok = reinterpret_cast (BIO_get_data(bio)); - if (!BIO_get_init(bio) || !sok) + if (!BIO_get_init(bio) || !sok) { return -1; + } - try - { - const size_t n = sok->m_wrapped->sendRawNonBlocking - (reinterpret_cast (buf), len); + try { - if (n == 0 && sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK) - { + const size_t n = sok->m_wrapped->sendRawNonBlocking( + reinterpret_cast (buf), len + ); + + if (n == 0 && sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK) { BIO_set_retry_write(bio); return -1; } return static_cast (n); - } - catch (exception& e) - { + + } catch (exception& e) { + // Workaround for passing C++ exceptions from C BIO functions sok->m_ex.reset(e.clone()); return -1; @@ -615,33 +631,35 @@ int TLSSocket_OpenSSL::bio_write(BIO* bio, const char* buf, int len) // static -int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) -{ +int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) { + BIO_clear_retry_flags(bio); - if (buf == NULL || len <= 0) + if (buf == NULL || len <= 0) { return -1; + } TLSSocket_OpenSSL *sok = reinterpret_cast (BIO_get_data(bio)); - if (!BIO_get_init(bio) || !sok) + if (!BIO_get_init(bio) || !sok) { return -1; + } - try - { - const size_t n = sok->m_wrapped->receiveRaw - (reinterpret_cast (buf), len); + try { - if (n == 0 || sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK) - { + const size_t n = sok->m_wrapped->receiveRaw( + reinterpret_cast (buf), len + ); + + if (n == 0 || sok->m_wrapped->getStatus() & socket::STATUS_WOULDBLOCK) { BIO_set_retry_read(bio); return -1; } return static_cast (n); - } - catch (exception& e) - { + + } catch (exception& e) { + // Workaround for passing C++ exceptions from C BIO functions sok->m_ex.reset(e.clone()); return -1; @@ -650,50 +668,50 @@ int TLSSocket_OpenSSL::bio_read(BIO* bio, char* buf, int len) // static -int TLSSocket_OpenSSL::bio_puts(BIO* bio, const char* str) -{ +int TLSSocket_OpenSSL::bio_puts(BIO* bio, const char* str) { + return bio_write(bio, str, static_cast (strlen(str))); } // static -long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* /* ptr */) -{ +long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* /* ptr */) { + long ret = 1; - switch (cmd) - { - case BIO_CTRL_INFO: + switch (cmd) { - ret = 0; - break; + case BIO_CTRL_INFO: - case BIO_CTRL_GET_CLOSE: + ret = 0; + break; - ret = BIO_get_shutdown(bio); - break; + case BIO_CTRL_GET_CLOSE: - case BIO_CTRL_SET_CLOSE: + ret = BIO_get_shutdown(bio); + break; - BIO_set_shutdown(bio, static_cast (num)); - break; + case BIO_CTRL_SET_CLOSE: - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: + BIO_set_shutdown(bio, static_cast (num)); + break; - ret = 0; - break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: + ret = 0; + break; - ret = 1; - break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: - default: + ret = 1; + break; - ret = 0; - break; + default: + + ret = 0; + break; } return ret; @@ -701,8 +719,8 @@ long TLSSocket_OpenSSL::bio_ctrl(BIO* bio, int cmd, long num, void* /* ptr */) // static -int TLSSocket_OpenSSL::bio_create(BIO* bio) -{ +int TLSSocket_OpenSSL::bio_create(BIO* bio) { + BIO_set_init(bio, 0); BIO_set_num(bio, 0); BIO_set_data(bio, NULL); @@ -713,13 +731,13 @@ int TLSSocket_OpenSSL::bio_create(BIO* bio) // static -int TLSSocket_OpenSSL::bio_destroy(BIO* bio) -{ - if (bio == NULL) - return 0; +int TLSSocket_OpenSSL::bio_destroy(BIO* bio) { - if (BIO_get_shutdown(bio)) - { + if (!bio) { + return 0; + } + + if (BIO_get_shutdown(bio)) { BIO_set_data(bio, NULL); BIO_set_init(bio, 0); BIO_set_flags(bio, 0); diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp index 9f395051..e30df680 100644 --- a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -50,11 +50,15 @@ class TLSSession; class TLSSession_OpenSSL; -class TLSSocket_OpenSSL : public TLSSocket -{ +class TLSSocket_OpenSSL : public TLSSocket { + public: - TLSSocket_OpenSSL(const shared_ptr & session, const shared_ptr & sok); + TLSSocket_OpenSSL( + const shared_ptr & session, + const shared_ptr & sok + ); + ~TLSSocket_OpenSSL(); diff --git a/src/vmime/net/tracer.cpp b/src/vmime/net/tracer.cpp index b3610cdd..66afb360 100644 --- a/src/vmime/net/tracer.cpp +++ b/src/vmime/net/tracer.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,13 +37,14 @@ namespace vmime { namespace net { -void tracer::traceReceiveBytes(const size_t count, const string& state) -{ +void tracer::traceReceiveBytes(const size_t count, const string& state) { + std::ostringstream oss; oss << "{..."; - if (!state.empty()) + if (!state.empty()) { oss << state << ": "; + } oss << count << " bytes of data...}"; @@ -51,13 +52,14 @@ void tracer::traceReceiveBytes(const size_t count, const string& state) } -void tracer::traceSendBytes(const size_t count, const string& state) -{ +void tracer::traceSendBytes(const size_t count, const string& state) { + std::ostringstream oss; oss << "{..."; - if (!state.empty()) + if (!state.empty()) { oss << state << ": "; + } oss << count << " bytes of data...}"; diff --git a/src/vmime/net/tracer.hpp b/src/vmime/net/tracer.hpp index 853455a3..74724630 100644 --- a/src/vmime/net/tracer.hpp +++ b/src/vmime/net/tracer.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,12 +44,13 @@ class service; /** Base class for an object used to trace network communication * between the client and the server. */ +class VMIME_EXPORT tracer : public object { -class VMIME_EXPORT tracer : public object -{ public: - virtual ~tracer() { } + virtual ~tracer() { + + } /** Trace raw bytes which have been received. * @@ -79,15 +80,15 @@ public: }; - /** A class to create 'tracer' objects. */ +class VMIME_EXPORT tracerFactory : public object { -class VMIME_EXPORT tracerFactory : public object -{ public: - virtual ~tracerFactory() { } + virtual ~tracerFactory() { + + } /** Creates a tracer for the specified service. * diff --git a/src/vmime/net/transport.cpp b/src/vmime/net/transport.cpp index 1b69995c..f87648a3 100644 --- a/src/vmime/net/transport.cpp +++ b/src/vmime/net/transport.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,30 +43,34 @@ namespace vmime { namespace net { -transport::transport(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth) - : service(sess, infos, auth) -{ +transport::transport( + const shared_ptr & sess, + const serviceInfos& infos, + const shared_ptr & auth +) + : service(sess, infos, auth) { + } -shared_ptr transport::processHeaderField(const shared_ptr & field) -{ - if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::BCC)) - { +shared_ptr transport::processHeaderField(const shared_ptr & field) { + + if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::BCC)) { + // Remove Bcc headers from the message, as required by the RFC. // Some SMTP server automatically strip this header (Postfix, qmail), // and others have an option for this (Exim). return null; - } - else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::RETURN_PATH)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::RETURN_PATH)) { + // RFC-2821: Return-Path header is added by the final transport system // that delivers the message to its recipient. Then, it should not be // transmitted to MSA. return null; - } - else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::ORIGINAL_RECIPIENT)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(field->getName(), fields::ORIGINAL_RECIPIENT)) { + // RFC-2298: Delivering MTA may add the Original-Recipient header and // discard existing one; so, no need to send it. return null; @@ -77,59 +81,71 @@ shared_ptr transport::processHeaderField(const shared_ptr & header) -{ - if (header->getFieldCount() == 0) +void transport::processHeader(const shared_ptr
& header) { + + if (header->getFieldCount() == 0) { return; + } // Remove/replace fields - for (size_t idx = header->getFieldCount() ; idx != 0 ; --idx) - { + for (size_t idx = header->getFieldCount() ; idx != 0 ; --idx) { + shared_ptr field = header->getFieldAt(idx - 1); shared_ptr newField = processHeaderField(field); - if (newField == NULL) + if (newField == NULL) { header->removeField(field); - else if (newField != field) + } else if (newField != field) { header->replaceField(field, newField); + } } // Add missing header fields // -- Date - if (!header->hasField(fields::DATE)) + if (!header->hasField(fields::DATE)) { header->Date()->setValue(datetime::now()); + } // -- Mime-Version - if (!header->hasField(fields::MIME_VERSION)) + if (!header->hasField(fields::MIME_VERSION)) { header->MimeVersion()->setValue(string(SUPPORTED_MIME_VERSION)); + } // -- Message-Id - if (!header->hasField(fields::MESSAGE_ID)) + if (!header->hasField(fields::MESSAGE_ID)) { header->MessageId()->setValue(messageId::generateId()); -} - - -static void extractMailboxes - (mailboxList& recipients, const addressList& list) -{ - for (size_t i = 0 ; i < list.getAddressCount() ; ++i) - { - shared_ptr mbox = dynamicCast (list.getAddressAt(i)->clone()); - - if (mbox != NULL) - recipients.appendMailbox(mbox); } } -void transport::send(const shared_ptr & msg, utility::progressListener* progress) -{ +static void extractMailboxes( + mailboxList& recipients, + const addressList& list +) { + + for (size_t i = 0 ; i < list.getAddressCount() ; ++i) { + + shared_ptr mbox = dynamicCast (list.getAddressAt(i)->clone()); + + if (mbox) { + recipients.appendMailbox(mbox); + } + } +} + + +void transport::send( + const shared_ptr & msg, + utility::progressListener* progress +) { + // Extract expeditor shared_ptr fromMbox = msg->getHeader()->findFieldValue (fields::FROM); - if (!fromMbox) + if (!fromMbox) { throw exceptions::no_expeditor(); + } mailbox expeditor = *fromMbox; @@ -139,10 +155,11 @@ void transport::send(const shared_ptr & msg, utility::progressLi mailbox sender; - if (!senderMbox) + if (!senderMbox) { sender = expeditor; - else + } else { sender = *senderMbox; + } // Extract recipients mailboxList recipients; @@ -151,22 +168,23 @@ void transport::send(const shared_ptr & msg, utility::progressLi shared_ptr addresses = msg->getHeader()->findFieldValue (fields::TO); - if (addresses) + if (addresses) { extractMailboxes(recipients, *addresses); + } // -- "Cc" field - addresses = - msg->getHeader()->findFieldValue (fields::CC); + addresses = msg->getHeader()->findFieldValue (fields::CC); - if (addresses) + if (addresses) { extractMailboxes(recipients, *addresses); + } // -- "Bcc" field - addresses = - msg->getHeader()->findFieldValue (fields::BCC); + addresses = msg->getHeader()->findFieldValue (fields::BCC); - if (addresses) + if (addresses) { extractMailboxes(recipients, *addresses); + } // Process message header by removing fields that should be removed // before transmitting the message to MSA, and adding missing fields @@ -177,18 +195,21 @@ void transport::send(const shared_ptr & msg, utility::progressLi // To avoid cloning message body (too much overhead), use processed // header during the time we are generating the message to a stream. // Revert it back to original header after. - struct XChangeMsgHeader - { - XChangeMsgHeader(const shared_ptr & _msg, - const shared_ptr & _hdr) - : msg(_msg), hdr(msg->getHeader()) - { + struct XChangeMsgHeader { + + XChangeMsgHeader( + const shared_ptr & _msg, + const shared_ptr & _hdr + ) + : msg(_msg), + hdr(msg->getHeader()) { + // Set new header msg->setHeader(_hdr); } - ~XChangeMsgHeader() - { + ~XChangeMsgHeader() { + // Revert original header msg->setHeader(hdr); } @@ -197,16 +218,21 @@ void transport::send(const shared_ptr & msg, utility::progressLi shared_ptr msg; shared_ptr hdr; + } headerExchanger(msg, hdr); send(msg, expeditor, recipients, progress, sender); } -void transport::send - (const shared_ptr & msg, const mailbox& expeditor, const mailboxList& recipients, - utility::progressListener* progress, const mailbox& sender) -{ +void transport::send( + const shared_ptr & msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress, + const mailbox& sender +) { + // Generate the message, "stream" it and delegate the sending // to the generic send() function. std::ostringstream oss; @@ -222,9 +248,9 @@ void transport::send } -transport::Type transport::getType() const -{ - return (TYPE_TRANSPORT); +transport::Type transport::getType() const { + + return TYPE_TRANSPORT; } diff --git a/src/vmime/net/transport.hpp b/src/vmime/net/transport.hpp index a54f041e..2f9878d0 100644 --- a/src/vmime/net/transport.hpp +++ b/src/vmime/net/transport.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,12 +51,15 @@ namespace net { /** A transport service. * Encapsulate protocols that can send messages. */ +class VMIME_EXPORT transport : public service { -class VMIME_EXPORT transport : public service -{ protected: - transport(const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth); + transport( + const shared_ptr & sess, + const serviceInfos& infos, + const shared_ptr & auth + ); public: @@ -67,7 +70,10 @@ public: * @param msg message to send * @param progress progress listener, or NULL if not used */ - virtual void send(const shared_ptr & msg, utility::progressListener* progress = NULL); + virtual void send( + const shared_ptr & msg, + utility::progressListener* progress = NULL + ); /** Send a message over this transport service. * @@ -78,13 +84,14 @@ public: * @param progress progress listener, or NULL if not used * @param sender envelope sender (if empty, expeditor will be used) */ - virtual void send - (const mailbox& expeditor, - const mailboxList& recipients, - utility::inputStream& is, - const size_t size, - utility::progressListener* progress = NULL, - const mailbox& sender = mailbox()) = 0; + virtual void send( + const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox() + ) = 0; /** Send a message over this transport service. * The default implementation simply generates the whole message into @@ -96,12 +103,13 @@ public: * @param progress progress listener, or NULL if not used * @param sender envelope sender (if empty, expeditor will be used) */ - virtual void send - (const shared_ptr & msg, - const mailbox& expeditor, - const mailboxList& recipients, - utility::progressListener* progress = NULL, - const mailbox& sender = mailbox()); + virtual void send( + const shared_ptr & msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox() + ); Type getType() const; diff --git a/src/vmime/object.cpp b/src/vmime/object.cpp index d07c3c19..f61b2ac9 100644 --- a/src/vmime/object.cpp +++ b/src/vmime/object.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,28 +25,27 @@ #include "vmime/object.hpp" -namespace vmime -{ +namespace vmime { -object::object() -{ +object::object() { + } -object::object(const object&) -{ +object::object(const object&) { + } -object& object::operator=(const object&) -{ +object& object::operator=(const object&) { + return *this; } -object::~object() -{ +object::~object() { + } diff --git a/src/vmime/object.hpp b/src/vmime/object.hpp index ecaafc1e..5869d383 100644 --- a/src/vmime/object.hpp +++ b/src/vmime/object.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/types.hpp" -namespace vmime -{ +namespace vmime { /** Base object for all objects in the library. */ +class VMIME_EXPORT object { -class VMIME_EXPORT object -{ protected: object(); @@ -52,4 +50,3 @@ protected: #endif // VMIME_OBJECT_HPP_INCLUDED - diff --git a/src/vmime/parameter.cpp b/src/vmime/parameter.cpp index bba43f50..41b37a46 100644 --- a/src/vmime/parameter.cpp +++ b/src/vmime/parameter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,36 +31,38 @@ #include "vmime/utility/outputStreamStringAdapter.hpp" -namespace vmime -{ +namespace vmime { parameter::parameter(const string& name) - : m_name(name), m_value(make_shared ()) -{ + : m_name(name), + m_value(make_shared ()) { + } parameter::parameter(const string& name, const word& value) - : m_name(name), m_value(make_shared (value)) -{ + : m_name(name), + m_value(make_shared (value)) { + } parameter::parameter(const string& name, const string& value) - : m_name(name), m_value(make_shared (value)) -{ + : m_name(name), + m_value(make_shared (value)) { + } parameter::parameter(const parameter&) - : component() -{ + : component() { + } -shared_ptr parameter::clone() const -{ +shared_ptr parameter::clone() const { + shared_ptr p = make_shared (m_name); p->copyFrom(*this); @@ -68,8 +70,8 @@ shared_ptr parameter::clone() const } -void parameter::copyFrom(const component& other) -{ +void parameter::copyFrom(const component& other) { + const parameter& param = dynamic_cast (other); m_name = param.m_name; @@ -77,27 +79,27 @@ void parameter::copyFrom(const component& other) } -parameter& parameter::operator=(const parameter& other) -{ +parameter& parameter::operator=(const parameter& other) { + copyFrom(other); return (*this); } -const string& parameter::getName() const -{ +const string& parameter::getName() const { + return m_name; } -const word& parameter::getValue() const -{ +const word& parameter::getValue() const { + return *m_value; } -void parameter::setValue(const component& value) -{ +void parameter::setValue(const component& value) { + std::ostringstream oss; utility::outputStreamAdapter vos(oss); @@ -107,30 +109,39 @@ void parameter::setValue(const component& value) } -void parameter::setValue(const word& value) -{ +void parameter::setValue(const word& value) { + *m_value = value; } -void parameter::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void parameter::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + m_value->setBuffer(string(buffer.begin() + position, buffer.begin() + end)); - if (ctx.getInternationalizedEmailSupport()) + if (ctx.getInternationalizedEmailSupport()) { m_value->setCharset(charset(charsets::UTF_8)); - else + } else { m_value->setCharset(charset(charsets::US_ASCII)); + } - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void parameter::parse(const parsingContext& ctx, const std::vector & chunks) -{ +void parameter::parse( + const parsingContext& ctx, + const std::vector & chunks +) { + bool foundCharsetChunk = false; charset ch(charsets::US_ASCII); @@ -139,29 +150,30 @@ void parameter::parse(const parsingContext& ctx, const std::vector & std::ostringstream value; value.imbue(std::locale::classic()); - for (std::vector ::size_type i = 0 ; i < chunks.size() ; ++i) - { + for (std::vector ::size_type i = 0 ; i < chunks.size() ; ++i) { + const valueChunk& chunk = chunks[i]; // Decode following data - if (chunk.encoded) - { + if (chunk.encoded) { + const size_t len = chunk.data.length(); size_t pos = 0; // If this is the first encoded chunk, extract charset // and language information - if (!foundCharsetChunk) - { + if (!foundCharsetChunk) { + // Eg. "us-ascii'en'This%20is%20even%20more%20" size_t q = chunk.data.find_first_of('\''); - if (q != string::npos) - { + if (q != string::npos) { + const string chs = chunk.data.substr(0, q); - if (!chs.empty()) + if (!chs.empty()) { ch = charset(chs); + } ++q; pos = q; @@ -169,8 +181,8 @@ void parameter::parse(const parsingContext& ctx, const std::vector & q = chunk.data.find_first_of('\'', pos); - if (q != string::npos) - { + if (q != string::npos) { + // Extract language lang = chunk.data.substr(pos, q - pos); @@ -181,59 +193,59 @@ void parameter::parse(const parsingContext& ctx, const std::vector & foundCharsetChunk = true; } - for (size_t i = pos ; i < len ; ++i) - { + for (size_t i = pos ; i < len ; ++i) { + const char c = chunk.data[i]; - if (c == '%' && i + 2 < len) - { + if (c == '%' && i + 2 < len) { + unsigned int v = 0; // First char - switch (chunk.data[i + 1]) - { - case 'a': case 'A': v += 10; break; - case 'b': case 'B': v += 11; break; - case 'c': case 'C': v += 12; break; - case 'd': case 'D': v += 13; break; - case 'e': case 'E': v += 14; break; - case 'f': case 'F': v += 15; break; - default: // assume 0-9 + switch (chunk.data[i + 1]) { - v += (chunk.data[i + 1] - '0'); - break; + case 'a': case 'A': v += 10; break; + case 'b': case 'B': v += 11; break; + case 'c': case 'C': v += 12; break; + case 'd': case 'D': v += 13; break; + case 'e': case 'E': v += 14; break; + case 'f': case 'F': v += 15; break; + default: // assume 0-9 + + v += (chunk.data[i + 1] - '0'); + break; } v *= 16; // Second char - switch (chunk.data[i + 2]) - { - case 'a': case 'A': v += 10; break; - case 'b': case 'B': v += 11; break; - case 'c': case 'C': v += 12; break; - case 'd': case 'D': v += 13; break; - case 'e': case 'E': v += 14; break; - case 'f': case 'F': v += 15; break; - default: // assume 0-9 + switch (chunk.data[i + 2]) { - v += (chunk.data[i + 2] - '0'); - break; + case 'a': case 'A': v += 10; break; + case 'b': case 'B': v += 11; break; + case 'c': case 'C': v += 12; break; + case 'd': case 'D': v += 13; break; + case 'e': case 'E': v += 14; break; + case 'f': case 'F': v += 15; break; + default: // assume 0-9 + + v += (chunk.data[i + 2] - '0'); + break; } value << static_cast (v); i += 2; // skip next 2 chars - } - else - { + + } else { + value << c; } } - } + // Simply copy data, as it is not encoded - else - { + } else { + // This syntax is non-standard (expressly prohibited // by RFC-2047), but is used by Mozilla: // @@ -246,20 +258,20 @@ void parameter::parse(const parsingContext& ctx, const std::vector & vmime::text t; t.parse(ctx, chunk.data); - if (t.getWordCount() != 0) - { + if (t.getWordCount() != 0) { + value << t.getWholeBuffer(); - if (!foundCharsetChunk) - { + if (!foundCharsetChunk) { + // 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) - { + 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; } @@ -275,10 +287,13 @@ void parameter::parse(const parsingContext& ctx, const std::vector & } -void parameter::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void parameter::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + const string& name = m_name; const string& value = m_value->getBuffer(); @@ -305,8 +320,8 @@ void parameter::generateImpl size_t pos = curLinePos; - if (pos + name.length() + 10 + value.length() > ctx.getMaxLineLength()) - { + if (pos + name.length() + 10 + value.length() > ctx.getMaxLineLength()) { + sevenBitStream << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE_LENGTH; } @@ -316,54 +331,53 @@ void parameter::generateImpl size_t valueLength = 0; // Use worst-case length name.length()+2 for 'name=' part of line - for (size_t i = 0 ; (i < value.length()) && (pos + name.length() + 2 + valueLength < ctx.getMaxLineLength() - 4) ; ++i, ++valueLength) - { - switch (value[i]) - { - // Characters that need to be quoted _and_ escaped - case '"': - case '\\': - // Other characters that need quoting - case ' ': - case '\t': - case '(': - case ')': - case '<': - case '>': - case '@': - case ',': - case ';': - case ':': - case '/': - case '[': - case ']': - case '?': - case '=': + for (size_t i = 0 ; (i < value.length()) && (pos + name.length() + 2 + valueLength < ctx.getMaxLineLength() - 4) ; ++i, ++valueLength) { - needQuoting = true; - break; + switch (value[i]) { - default: + // Characters that need to be quoted _and_ escaped + case '"': + case '\\': + // Other characters that need quoting + case ' ': + case '\t': + case '(': + case ')': + case '<': + case '>': + case '@': + case ',': + case ';': + case ':': + case '/': + case '[': + case ']': + case '?': + case '=': - if (!parserHelpers::isAscii(value[i])) - { - needQuotedPrintable = true; needQuoting = true; - } + break; - break; + default: + + if (!parserHelpers::isAscii(value[i])) { + needQuotedPrintable = true; + needQuoting = true; + } + + break; } } const bool cutValue = (valueLength != value.length()); // has the value been cut? - if (needQuoting) - { + if (needQuoting) { + sevenBitStream << name << "=\""; pos += name.length() + 2; - } - else - { + + } else { + sevenBitStream << name << "="; pos += name.length() + 1; } @@ -377,51 +391,51 @@ void parameter::generateImpl bool extended = alwaysEncode; if ((needQuotedPrintable || cutValue || !m_value->getLanguage().empty()) && - genMode != generationContext::PARAMETER_VALUE_NO_ENCODING) - { + genMode != generationContext::PARAMETER_VALUE_NO_ENCODING) { + // Send the name in quoted-printable, so outlook express et.al. // will understand the real filename size_t oldLen = sevenBitBuffer.length(); m_value->generate(sevenBitStream); pos += sevenBitBuffer.length() - oldLen; extended = true; // also send with RFC-2231 encoding - } - else - { + + } else { + // Do not chop off this value, but just add the complete name as one header line. for (size_t i = 0, n = value.length(), curValueLength = 0 ; - i < n && curValueLength < valueLength ; ++i) - { + i < n && curValueLength < valueLength ; ++i) { + const char_t c = value[i]; - if (/* needQuoting && */ (c == '"' || c == '\\')) // 'needQuoting' is implicit - { + if (/* needQuoting && */ (c == '"' || c == '\\')) { // 'needQuoting' is implicit + sevenBitStream << '\\' << value[i]; // escape 'x' with '\x' pos += 2; - } - else if (parserHelpers::isAscii(c)) - { + + } else if (parserHelpers::isAscii(c)) { + sevenBitStream << value[i]; ++pos; ++curValueLength; - } - else - { + + } else { + extended = true; } } } // !needQuotedPrintable - if (needQuoting) - { + if (needQuoting) { + sevenBitStream << '"'; ++pos; } if (genMode == generationContext::PARAMETER_VALUE_RFC2047_ONLY || - genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) - { + genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) { + os << sevenBitBuffer; } @@ -429,16 +443,16 @@ void parameter::generateImpl // or is too long for a single line if ((extended || cutValue) && genMode != generationContext::PARAMETER_VALUE_NO_ENCODING && - genMode != generationContext::PARAMETER_VALUE_RFC2047_ONLY) - { + genMode != generationContext::PARAMETER_VALUE_RFC2047_ONLY) { + + + if (genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) { - if (genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) - { os << ';'; ++pos; - } - else - { + + } else { + // The data output to 'sevenBitBuffer' will be discarded in this case pos = curLinePos; } @@ -466,8 +480,8 @@ void parameter::generateImpl name.length() + 4 /* *0*= */ + 2 /* '' */ + m_value->getCharset().getName().length(); - if (pos + firstSectionLength + 5 >= ctx.getMaxLineLength()) - { + if (pos + firstSectionLength + 5 >= ctx.getMaxLineLength()) { + os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE_LENGTH; } @@ -479,61 +493,60 @@ void parameter::generateImpl string currentSection; size_t currentSectionLength = firstSectionLength; - for (size_t i = 0 ; i < value.length() ; ++i) - { + for (size_t i = 0 ; i < value.length() ; ++i) { + // Check whether we should start a new line (taking into // account the next character will be encoded = worst case) - if (currentSectionLength + 3 >= ctx.getMaxLineLength()) - { + if (currentSectionLength + 3 >= ctx.getMaxLineLength()) { + sectionText.push_back(currentSection); sectionCount++; currentSection.clear(); - currentSectionLength = NEW_LINE_SEQUENCE_LENGTH - + name.length() + 6; + currentSectionLength = NEW_LINE_SEQUENCE_LENGTH + name.length() + 6; } // Output next character const char_t c = value[i]; bool encode = false; - switch (c) - { - // special characters - case ' ': - case '\t': - case '\r': - case '\n': - case '%': - case '"': - case ';': - case ',': - case '(': - case ')': - case '<': - case '>': - case '@': - case ':': - case '/': - case '[': - case ']': - case '?': - case '=': + switch (c) { - encode = true; - break; + // special characters + case ' ': + case '\t': + case '\r': + case '\n': + case '%': + case '"': + case ';': + case ',': + case '(': + case ')': + case '<': + case '>': + case '@': + case ':': + case '/': + case '[': + case ']': + case '?': + case '=': - default: + encode = true; + break; - encode = (!parserHelpers::isPrint(c) || - !parserHelpers::isAscii(c) || - alwaysEncode); + default: - break; + encode = (!parserHelpers::isPrint(c) || + !parserHelpers::isAscii(c) || + alwaysEncode); + + break; } - if (encode) // need encoding - { + if (encode) { // need encoding + const int h1 = static_cast (c) / 16; const int h2 = static_cast (c) % 16; @@ -543,9 +556,9 @@ void parameter::generateImpl pos += 3; currentSectionLength += 3; - } - else - { + + } else { + currentSection += value[i]; ++pos; @@ -553,44 +566,44 @@ void parameter::generateImpl } } - if (!currentSection.empty()) - { + if (!currentSection.empty()) { + sectionText.push_back(currentSection); sectionCount++; } // Output sections - for (int sectionNumber = 0 ; sectionNumber < sectionCount ; ++sectionNumber) - { + for (int sectionNumber = 0 ; sectionNumber < sectionCount ; ++sectionNumber) { + os << name; - if (sectionCount != 1) // no section specifier when only a single one - { + if (sectionCount != 1) { // no section specifier when only a single one + os << '*'; os << sectionNumber; } os << "*="; - if (sectionNumber == 0) - { + if (sectionNumber == 0) { + os << m_value->getCharset().getName(); os << '\'' << /* No language */ '\''; } os << sectionText[sectionNumber]; - if (sectionNumber + 1 < sectionCount) - { + if (sectionNumber + 1 < sectionCount) { + os << ';'; os << NEW_LINE_SEQUENCE; pos = NEW_LINE_SEQUENCE_LENGTH; } } - } - else if (!(genMode == generationContext::PARAMETER_VALUE_RFC2047_ONLY || - genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047)) - { + + } else if (!(genMode == generationContext::PARAMETER_VALUE_RFC2047_ONLY || + genMode == generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047)) { + // The value does not contain 8-bit characters and // is short enough for a single line. // "7bit/us-ascii" will suffice in this case. @@ -599,13 +612,14 @@ void parameter::generateImpl os << sevenBitBuffer; } - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } -size_t parameter::getGeneratedSize(const generationContext& ctx) -{ +size_t parameter::getGeneratedSize(const generationContext& ctx) { + const string& name = m_name; const string& value = m_value->getBuffer(); @@ -638,8 +652,8 @@ size_t parameter::getGeneratedSize(const generationContext& ctx) } -const std::vector > parameter::getChildComponents() -{ +const std::vector > parameter::getChildComponents() { + std::vector > list; list.push_back(m_value); @@ -649,4 +663,3 @@ const std::vector > parameter::getChildComponents() } // vmime - diff --git a/src/vmime/parameter.hpp b/src/vmime/parameter.hpp index 92ac95d7..f965bade 100644 --- a/src/vmime/parameter.hpp +++ b/src/vmime/parameter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,12 +30,11 @@ #include "vmime/word.hpp" -namespace vmime -{ +namespace vmime { -class VMIME_EXPORT parameter : public component -{ +class VMIME_EXPORT parameter : public component { + friend class parameterizedHeaderField; private: @@ -73,8 +72,7 @@ public: * as defined in RFC-2231/3. This is used when * calling parse() on the parameter. */ - struct valueChunk - { + struct valueChunk { bool encoded; string data; }; @@ -121,8 +119,8 @@ public: * @return value */ template - const T getValueAs() const - { + const T getValueAs() const { + T ret; ret.parse(m_value->getBuffer()); @@ -144,22 +142,27 @@ public: protected: - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; private: - void parse(const parsingContext& ctx, const std::vector & chunks); + void parse( + const parsingContext& ctx, + const std::vector & chunks + ); string m_name; diff --git a/src/vmime/parameterizedHeaderField.cpp b/src/vmime/parameterizedHeaderField.cpp index 0d90692b..6815fad1 100644 --- a/src/vmime/parameterizedHeaderField.cpp +++ b/src/vmime/parameterizedHeaderField.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -26,17 +26,16 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { -parameterizedHeaderField::parameterizedHeaderField() -{ +parameterizedHeaderField::parameterizedHeaderField() { + } -parameterizedHeaderField::~parameterizedHeaderField() -{ +parameterizedHeaderField::~parameterizedHeaderField() { + removeAllParameters(); } @@ -67,8 +66,8 @@ parameterizedHeaderField::~parameterizedHeaderField() #ifndef VMIME_BUILDING_DOC -struct paramInfo -{ +struct paramInfo { + bool extended; std::vector value; size_t start; @@ -78,10 +77,14 @@ struct paramInfo #endif // VMIME_BUILDING_DOC -void parameterizedHeaderField::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void parameterizedHeaderField::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pstart; @@ -89,8 +92,7 @@ void parameterizedHeaderField::parseImpl // Skip non-significant whitespaces size_t valueStart = position; - while (p < pend && parserHelpers::isSpace(*p)) - { + while (p < pend && parserHelpers::isSpace(*p)) { ++p; ++valueStart; } @@ -98,15 +100,16 @@ void parameterizedHeaderField::parseImpl // Advance up to ';', if any size_t valueLength = 0; - while (p < pend && *p != ';' && (!parserHelpers::isSpace(*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; } // Trim whitespaces at the end of the value - while (valueLength > 0 && parserHelpers::isSpace(buffer[valueStart + valueLength - 1])) + while (valueLength > 0 && parserHelpers::isSpace(buffer[valueStart + valueLength - 1])) { --valueLength; + } // Parse value getValue()->parse(ctx, buffer, valueStart, valueStart + valueLength); @@ -115,18 +118,19 @@ void parameterizedHeaderField::parseImpl removeAllParameters(); // If there is one or more parameters following... - if (p < pend) - { + if (p < pend) { + std::map params; - if (*p != ';') - { - while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text + if (*p != ';') { + + while (p < pend && *p != ';') { // FIXME: support ";" inside quoted or RFC-2047-encoded text ++p; + } } - while (*p == ';') - { + while (*p == ';') { + // Skip ';' ++p; @@ -134,24 +138,26 @@ void parameterizedHeaderField::parseImpl const size_t attrStart = position + (p - pstart); - while (p < pend && !(*p == ';' || *p == '=')) + while (p < pend && !(*p == ';' || *p == '=')) { ++p; + } + + if (p >= pend || *p == ';') { - if (p >= pend || *p == ';') - { // Hmmmm... we didn't found an '=' sign. // This parameter may not be valid so try to advance // to the next one, if there is one. while (p < pend && *p != ';') ++p; - } - else - { + + } else { + // Extract the attribute name size_t attrEnd = position + (p - pstart); - while (attrEnd != attrStart && parserHelpers::isSpace(buffer[attrEnd - 1])) + while (attrEnd != attrStart && parserHelpers::isSpace(buffer[attrEnd - 1])) { --attrEnd; + } // Skip '=' ++p; @@ -163,8 +169,8 @@ void parameterizedHeaderField::parseImpl string value; // -- this is a quoted-string - if (*p == '"') - { + if (*p == '"') { + // Skip '"' ++p; @@ -175,74 +181,84 @@ void parameterizedHeaderField::parseImpl std::ostringstream ss; size_t start = position + (p - pstart); - for ( ; p < pend && !stop ; ++p) - { - if (escape) - { + for ( ; p < pend && !stop ; ++p) { + + if (escape) { + escape = false; start = position + (p - pstart); - } - else - { - switch (*p) - { - case '"': - { - ss << string(buffer.begin() + start, - buffer.begin() + position + (p - pstart)); - stop = true; - break; - } - case '\\': - { - ss << string(buffer.begin() + start, - buffer.begin() + position + (p - pstart)); + } else { - escape = true; - break; - } + switch (*p) { + + case '"': { + + ss << string( + buffer.begin() + start, + buffer.begin() + position + (p - pstart) + ); + + stop = true; + break; + } + case '\\': { + + ss << string( + buffer.begin() + start, + buffer.begin() + position + (p - pstart) + ); + + escape = true; + break; + } } } } - if (!stop) - { - ss << string(buffer.begin() + start, - buffer.begin() + position + (p - pstart)); + if (!stop) { + + ss << string( + buffer.begin() + start, + buffer.begin() + position + (p - pstart) + ); } value = ss.str(); - } + // -- the value is a simple token - else - { + } else { + const size_t valStart = position + (p - pstart); - while (p < pend && *p != ';') + while (p < pend && *p != ';') { ++p; + } size_t valEnd = position + (p - pstart); - while (valEnd != valStart && parserHelpers::isSpace(buffer[valEnd - 1])) + while (valEnd != valStart && parserHelpers::isSpace(buffer[valEnd - 1])) { --valEnd; + } - value = string(buffer.begin() + valStart, - buffer.begin() + valEnd); + value = string( + buffer.begin() + valStart, + buffer.begin() + valEnd + ); } // Don't allow ill-formed parameters - if (attrStart != attrEnd && value.length()) - { + if (attrStart != attrEnd && value.length()) { + string name(buffer.begin() + attrStart, buffer.begin() + attrEnd); // Check for RFC-2231 extended parameters bool extended = false; bool encoded = false; - if (name[name.length() - 1] == '*') - { + if (name[name.length() - 1] == '*') { + name.erase(name.end() - 1, name.end()); extended = true; @@ -252,15 +268,15 @@ void parameterizedHeaderField::parseImpl // Check for RFC-2231 multi-section parameters const size_t star = name.find_last_of('*'); - if (star != string::npos) - { + if (star != string::npos) { + bool allDigits = true; - for (size_t i = star + 1 ; allDigits && (i < name.length()) ; ++i) + for (size_t i = star + 1 ; allDigits && (i < name.length()) ; ++i) { allDigits = parserHelpers::isDigit(name[i]); + } - if (allDigits) - { + if (allDigits) { name.erase(name.begin() + star, name.end()); extended = true; } @@ -273,13 +289,13 @@ void parameterizedHeaderField::parseImpl // Add/replace/modify the parameter const std::map ::iterator it = params.find(name); - if (it != params.end()) - { + if (it != params.end()) { + paramInfo& info = (*it).second; // An extended parameter replaces a normal one - if (!info.extended) - { + if (!info.extended) { + info.extended = extended; info.value.clear(); info.start = attrStart; @@ -292,9 +308,9 @@ void parameterizedHeaderField::parseImpl info.value.push_back(chunk); info.end = position + (p - pstart); - } - else - { + + } else { + parameter::valueChunk chunk; chunk.encoded = encoded; chunk.data = value; @@ -316,8 +332,8 @@ void parameterizedHeaderField::parseImpl } for (std::map ::const_iterator it = params.begin() ; - it != params.end() ; ++it) - { + it != params.end() ; ++it) { + const paramInfo& info = (*it).second; // Append this parameter to the list @@ -330,15 +346,19 @@ void parameterizedHeaderField::parseImpl } } - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void parameterizedHeaderField::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void parameterizedHeaderField::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + size_t pos = curLinePos; // Parent header field @@ -346,16 +366,17 @@ void parameterizedHeaderField::generateImpl // Parameters for (std::vector >::const_iterator - it = m_params.begin() ; it != m_params.end() ; ++it) - { + it = m_params.begin() ; it != m_params.end() ; ++it) { + os << "; "; pos += 2; (*it)->generate(ctx, os, pos, &pos); } - if (newLinePos) + if (newLinePos) { *newLinePos = pos; + } } @@ -364,8 +385,8 @@ size_t parameterizedHeaderField::getGeneratedSize(const generationContext& ctx) size_t size = headerField::getGeneratedSize(ctx); for (std::vector >::const_iterator - it = m_params.begin() ; it != m_params.end() ; ++it) - { + it = m_params.begin() ; it != m_params.end() ; ++it) { + size += 2; // "; " size += (*it)->getGeneratedSize(ctx); } @@ -374,8 +395,8 @@ size_t parameterizedHeaderField::getGeneratedSize(const generationContext& ctx) } -void parameterizedHeaderField::copyFrom(const component& other) -{ +void parameterizedHeaderField::copyFrom(const component& other) { + headerField::copyFrom(other); const parameterizedHeaderField& source = dynamic_cast(other); @@ -383,22 +404,22 @@ void parameterizedHeaderField::copyFrom(const component& other) removeAllParameters(); for (std::vector >::const_iterator i = source.m_params.begin() ; - i != source.m_params.end() ; ++i) - { + i != source.m_params.end() ; ++i) { + appendParameter(vmime::clone(*i)); } } -parameterizedHeaderField& parameterizedHeaderField::operator=(const parameterizedHeaderField& other) -{ +parameterizedHeaderField& parameterizedHeaderField::operator=(const parameterizedHeaderField& other) { + copyFrom(other); - return (*this); + return *this; } -bool parameterizedHeaderField::hasParameter(const string& paramName) const -{ +bool parameterizedHeaderField::hasParameter(const string& paramName) const { + const string name = utility::stringUtils::toLower(paramName); std::vector >::const_iterator pos = m_params.begin(); @@ -406,12 +427,12 @@ bool parameterizedHeaderField::hasParameter(const string& paramName) const for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos) {} - return (pos != end); + return pos != end; } -shared_ptr parameterizedHeaderField::findParameter(const string& paramName) const -{ +shared_ptr parameterizedHeaderField::findParameter(const string& paramName) const { + const string name = utility::stringUtils::toLower(paramName); // Find the first parameter that matches the specified name @@ -421,16 +442,17 @@ shared_ptr parameterizedHeaderField::findParameter(const string& par for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos) {} // No parameter with this name can be found - if (pos == end) + if (pos == end) { return null; + } // Else, return a reference to the existing parameter - return (*pos); + return *pos; } -shared_ptr parameterizedHeaderField::getParameter(const string& paramName) -{ +shared_ptr parameterizedHeaderField::getParameter(const string& paramName) { + const string name = utility::stringUtils::toLower(paramName); // Find the first parameter that matches the specified name @@ -440,154 +462,171 @@ shared_ptr parameterizedHeaderField::getParameter(const string& para for ( ; pos != end && utility::stringUtils::toLower((*pos)->getName()) != name ; ++pos) {} // If no parameter with this name can be found, create a new one - if (pos == end) - { + if (pos == end) { + shared_ptr param = make_shared (paramName); appendParameter(param); // Return a reference to the new parameter - return (param); - } + return param; + // Else, return a reference to the existing parameter - else - { - return (*pos); + } else { + + return *pos; } } -void parameterizedHeaderField::appendParameter(const shared_ptr & param) -{ +void parameterizedHeaderField::appendParameter(const shared_ptr & param) { + m_params.push_back(param); } -void parameterizedHeaderField::insertParameterBefore(const shared_ptr & beforeParam, const shared_ptr & param) -{ - const std::vector >::iterator it = std::find - (m_params.begin(), m_params.end(), beforeParam); +void parameterizedHeaderField::insertParameterBefore( + const shared_ptr & beforeParam, + const shared_ptr & param +) { - if (it == m_params.end()) + const std::vector >::iterator it = + std::find(m_params.begin(), m_params.end(), beforeParam); + + if (it == m_params.end()) { throw std::out_of_range("Invalid position"); + } m_params.insert(it, param); } -void parameterizedHeaderField::insertParameterBefore(const size_t pos, const shared_ptr & param) -{ - if (pos >= m_params.size()) +void parameterizedHeaderField::insertParameterBefore( + const size_t pos, + const shared_ptr & param +) { + + if (pos >= m_params.size()) { throw std::out_of_range("Invalid position"); + } m_params.insert(m_params.begin() + pos, param); } -void parameterizedHeaderField::insertParameterAfter(const shared_ptr & afterParam, const shared_ptr & param) -{ - const std::vector >::iterator it = std::find - (m_params.begin(), m_params.end(), afterParam); +void parameterizedHeaderField::insertParameterAfter( + const shared_ptr & afterParam, + const shared_ptr & param +) { - if (it == m_params.end()) + const std::vector >::iterator it = + std::find(m_params.begin(), m_params.end(), afterParam); + + if (it == m_params.end()) { throw std::out_of_range("Invalid position"); + } m_params.insert(it + 1, param); } -void parameterizedHeaderField::insertParameterAfter(const size_t pos, const shared_ptr & param) -{ - if (pos >= m_params.size()) +void parameterizedHeaderField::insertParameterAfter( + const size_t pos, + const shared_ptr & param +) { + + if (pos >= m_params.size()) { throw std::out_of_range("Invalid position"); + } m_params.insert(m_params.begin() + pos + 1, param); } -void parameterizedHeaderField::removeParameter(const shared_ptr & param) -{ - const std::vector >::iterator it = std::find - (m_params.begin(), m_params.end(), param); +void parameterizedHeaderField::removeParameter(const shared_ptr & param) { - if (it == m_params.end()) + const std::vector >::iterator it = + std::find(m_params.begin(), m_params.end(), param); + + if (it == m_params.end()) { throw std::out_of_range("Invalid position"); + } m_params.erase(it); } -void parameterizedHeaderField::removeParameter(const size_t pos) -{ +void parameterizedHeaderField::removeParameter(const size_t pos) { + const std::vector >::iterator it = m_params.begin() + pos; m_params.erase(it); } -void parameterizedHeaderField::removeAllParameters() -{ +void parameterizedHeaderField::removeAllParameters() { + m_params.clear(); } -size_t parameterizedHeaderField::getParameterCount() const -{ - return (m_params.size()); +size_t parameterizedHeaderField::getParameterCount() const { + + return m_params.size(); } -bool parameterizedHeaderField::isEmpty() const -{ - return (m_params.empty()); +bool parameterizedHeaderField::isEmpty() const { + + return m_params.empty(); } -const shared_ptr parameterizedHeaderField::getParameterAt(const size_t pos) -{ - return (m_params[pos]); +const shared_ptr parameterizedHeaderField::getParameterAt(const size_t pos) { + + return m_params[pos]; } -const shared_ptr parameterizedHeaderField::getParameterAt(const size_t pos) const -{ - return (m_params[pos]); +const shared_ptr parameterizedHeaderField::getParameterAt(const size_t pos) const { + + return m_params[pos]; } -const std::vector > parameterizedHeaderField::getParameterList() const -{ +const std::vector > parameterizedHeaderField::getParameterList() const { + std::vector > list; list.reserve(m_params.size()); for (std::vector >::const_iterator it = m_params.begin() ; - it != m_params.end() ; ++it) - { + it != m_params.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > parameterizedHeaderField::getParameterList() -{ - return (m_params); +const std::vector > parameterizedHeaderField::getParameterList() { + + return m_params; } -const std::vector > parameterizedHeaderField::getChildComponents() -{ +const std::vector > parameterizedHeaderField::getChildComponents() { + std::vector > list = headerField::getChildComponents(); for (std::vector >::iterator it = m_params.begin() ; - it != m_params.end() ; ++it) - { + it != m_params.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } diff --git a/src/vmime/parameterizedHeaderField.hpp b/src/vmime/parameterizedHeaderField.hpp index 113df16d..d884f1fb 100644 --- a/src/vmime/parameterizedHeaderField.hpp +++ b/src/vmime/parameterizedHeaderField.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,16 +31,14 @@ #include "vmime/exception.hpp" -namespace vmime -{ +namespace vmime { /** A header field that can also contain parameters (name=value pairs). * Parameters can be created using vmime::parameterFactory. */ +class VMIME_EXPORT parameterizedHeaderField : public headerField { -class VMIME_EXPORT parameterizedHeaderField : public headerField -{ friend class headerFieldFactory; protected: @@ -97,7 +95,10 @@ public: * @param param parameter to insert * @throw std::out_of_range if the parameter is not in the list */ - void insertParameterBefore(const shared_ptr & beforeParam, const shared_ptr & param); + void insertParameterBefore( + const shared_ptr & beforeParam, + const shared_ptr & param + ); /** Insert a new parameter before the specified position. * @@ -106,7 +107,10 @@ public: * @param param parameter to insert * @throw std::out_of_range if the position is out of range */ - void insertParameterBefore(const size_t pos, const shared_ptr & param); + void insertParameterBefore( + const size_t pos, + const shared_ptr & param + ); /** Insert a new parameter after the specified parameter. * @@ -114,7 +118,10 @@ public: * @param param parameter to insert * @throw std::out_of_range if the parameter is not in the list */ - void insertParameterAfter(const shared_ptr & afterParam, const shared_ptr & param); + void insertParameterAfter( + const shared_ptr & afterParam, + const shared_ptr & param + ); /** Insert a new parameter after the specified position. * @@ -122,7 +129,10 @@ public: * @param param parameter to insert * @throw std::out_of_range if the position is out of range */ - void insertParameterAfter(const size_t pos, const shared_ptr & param); + void insertParameterAfter( + const size_t pos, + const shared_ptr & param + ); /** Remove the specified parameter from the list. * @@ -189,18 +199,20 @@ private: protected: - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/parsedMessageAttachment.cpp b/src/vmime/parsedMessageAttachment.cpp index efe4a5b2..d50862ba 100644 --- a/src/vmime/parsedMessageAttachment.cpp +++ b/src/vmime/parsedMessageAttachment.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,38 +29,37 @@ #include "vmime/utility/outputStreamAdapter.hpp" -namespace vmime -{ +namespace vmime { parsedMessageAttachment::parsedMessageAttachment(const shared_ptr & msg) - : m_msg(msg) -{ + : m_msg(msg) { + } -const mediaType parsedMessageAttachment::getType() const -{ +const mediaType parsedMessageAttachment::getType() const { + return mediaType(mediaTypes::MESSAGE, mediaTypes::MESSAGE_RFC822); } -const text parsedMessageAttachment::getDescription() const -{ +const text parsedMessageAttachment::getDescription() const { + return text(); } -const word parsedMessageAttachment::getName() const -{ +const word parsedMessageAttachment::getName() const { + return word(); } -const shared_ptr parsedMessageAttachment::getData() const -{ - if (m_data == NULL) - { +const shared_ptr parsedMessageAttachment::getData() const { + + if (!m_data) { + std::ostringstream oss; utility::outputStreamAdapter os(oss); @@ -73,32 +72,32 @@ const shared_ptr parsedMessageAttachment::getData() const } -const encoding parsedMessageAttachment::getEncoding() const -{ +const encoding parsedMessageAttachment::getEncoding() const { + return encoding(encodingTypes::EIGHT_BIT); // not important } -shared_ptr parsedMessageAttachment::getPart() const -{ +shared_ptr parsedMessageAttachment::getPart() const { + return null; } -shared_ptr parsedMessageAttachment::getHeader() const -{ +shared_ptr parsedMessageAttachment::getHeader() const { + return null; } -shared_ptr parsedMessageAttachment::getMessage() const -{ +shared_ptr parsedMessageAttachment::getMessage() const { + return m_msg; } -void parsedMessageAttachment::generateIn(const shared_ptr & parent) const -{ +void parsedMessageAttachment::generateIn(const shared_ptr & parent) const { + // Create and append a new part for this attachment shared_ptr part = make_shared (); parent->getBody()->appendPart(part); @@ -113,4 +112,3 @@ void parsedMessageAttachment::generateIn(const shared_ptr & parent) co } // vmime - diff --git a/src/vmime/parsedMessageAttachment.hpp b/src/vmime/parsedMessageAttachment.hpp index 330cf869..2a5358e8 100644 --- a/src/vmime/parsedMessageAttachment.hpp +++ b/src/vmime/parsedMessageAttachment.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,14 +31,13 @@ #include "vmime/messageAttachment.hpp" -namespace vmime -{ +namespace vmime { /** A message attachment that can be generated into a message. */ -class VMIME_EXPORT parsedMessageAttachment : public messageAttachment -{ +class VMIME_EXPORT parsedMessageAttachment : public messageAttachment { + public: parsedMessageAttachment(const shared_ptr & msg); @@ -75,4 +74,3 @@ private: #endif // VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED - diff --git a/src/vmime/parserHelpers.hpp b/src/vmime/parserHelpers.hpp index 430487b4..cba43c6c 100644 --- a/src/vmime/parserHelpers.hpp +++ b/src/vmime/parserHelpers.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,60 +32,59 @@ -namespace vmime -{ +namespace vmime { -class parserHelpers -{ +class parserHelpers { + public: - static bool isSpace(const char_t c) - { - return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + static bool isSpace(const char_t c) { + + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; } - static bool isSpaceOrTab(const char_t c) - { - return (c == ' ' || c == '\t'); + static bool isSpaceOrTab(const char_t c) { + + return c == ' ' || c == '\t'; } - static bool isDigit(const char_t c) - { - return (c >= '0' && c <= '9'); + static bool isDigit(const char_t c) { + + return c >= '0' && c <= '9'; + } + + static bool isAlpha(const char_t c) { + + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } - static bool isAlpha(const char_t c) - { - return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); - } + static char_t toLower(const char_t c) { - - static char_t toLower(const char_t c) - { - if (c >= 'A' && c <= 'Z') + if (c >= 'A' && c <= 'Z') { return ('a' + (c - 'A')); - else + } else { return c; + } } // Checks whether a character is in the 7-bit US-ASCII charset - static bool isAscii(const char_t c) - { + static bool isAscii(const char_t c) { + const unsigned int x = static_cast (c); - return (x <= 127); + return x <= 127; } // Checks whether a character has a visual representation - static bool isPrint(const char_t c) - { + static bool isPrint(const char_t c) { + const unsigned int x = static_cast (c); - return (x >= 0x20 && x <= 0x7E); + return x >= 0x20 && x <= 0x7E; } @@ -99,22 +98,28 @@ public: * @return true if an EOL sequence has been found, or false if * no EOL sequence was found before the end of the buffer */ - static bool findEOL(const string& buffer, const size_t currentPos, const size_t end, size_t* eol) - { + static bool findEOL( + const string& buffer, + const size_t currentPos, + const size_t end, + size_t* eol + ) { + size_t pos = currentPos; - if (pos == end) + if (pos == end) { return false; + } + + while (pos < end) { + + if (buffer[pos] == '\r' && pos + 1 < end && buffer[pos + 1] == '\n') { - while (pos < end) - { - if (buffer[pos] == '\r' && pos + 1 < end && buffer[pos + 1] == '\n') - { *eol = pos + 2; return true; - } - else if (buffer[pos] == '\n') - { + + } else if (buffer[pos] == '\n') { + *eol = pos + 1; return true; } diff --git a/src/vmime/parsingContext.cpp b/src/vmime/parsingContext.cpp index c5da5151..0975e3d7 100644 --- a/src/vmime/parsingContext.cpp +++ b/src/vmime/parsingContext.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,35 +24,39 @@ #include "vmime/parsingContext.hpp" -namespace vmime -{ +namespace vmime { -parsingContext::parsingContext() : m_headerParseErrorRecovery(vmime::headerParseRecoveryMethod::SKIP_LINE) -{ +parsingContext::parsingContext() + : m_headerParseErrorRecovery(vmime::headerParseRecoveryMethod::SKIP_LINE) { + } parsingContext::parsingContext(const parsingContext& ctx) - : context(ctx), m_headerParseErrorRecovery(vmime::headerParseRecoveryMethod::SKIP_LINE) -{ + : context(ctx), + m_headerParseErrorRecovery(vmime::headerParseRecoveryMethod::SKIP_LINE) { + } -parsingContext& parsingContext::getDefaultContext() -{ +parsingContext& parsingContext::getDefaultContext() { + static parsingContext ctx; return ctx; } -headerParseRecoveryMethod::headerLineError parsingContext::getHeaderParseErrorRecoveryMethod() const -{ + +headerParseRecoveryMethod::headerLineError parsingContext::getHeaderParseErrorRecoveryMethod() const { + return m_headerParseErrorRecovery; } -void parsingContext::setHeaderParseErrorRecoveryMethod(headerParseRecoveryMethod::headerLineError recoveryMethod) -{ +void parsingContext::setHeaderParseErrorRecoveryMethod( + const headerParseRecoveryMethod::headerLineError recoveryMethod +) { + m_headerParseErrorRecovery = recoveryMethod; } diff --git a/src/vmime/parsingContext.hpp b/src/vmime/parsingContext.hpp index 1b1cd282..d13d94ef 100644 --- a/src/vmime/parsingContext.hpp +++ b/src/vmime/parsingContext.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,24 +28,23 @@ #include "vmime/context.hpp" -namespace vmime -{ +namespace vmime { - /** Provides runtime configurable options to provide flexibility in header parsing - */ - struct headerParseRecoveryMethod { - enum headerLineError { - SKIP_LINE = 0, - /* APPEND_TO_PREVIOUS_LINE = 1, */ - ASSUME_END_OF_HEADERS = 2 - }; +/** Provides runtime configurable options to provide flexibility in header parsing + */ +struct headerParseRecoveryMethod { + + enum headerLineError { + SKIP_LINE = 0, + /* APPEND_TO_PREVIOUS_LINE = 1, */ + ASSUME_END_OF_HEADERS = 2 }; +}; /** Holds configuration parameters used for parsing messages. */ +class VMIME_EXPORT parsingContext : public context { -class VMIME_EXPORT parsingContext : public context -{ public: parsingContext(); @@ -57,11 +56,13 @@ public: */ static parsingContext& getDefaultContext(); - /** Sets the recovery method when parsing a header encounters an error such as a failed fold or missing new line. + /** Sets the recovery method when parsing a header encounters an error + * such as a failed fold or missing new line. * - * @param recoveryMethod is one of vmime::headerParseRecoveryMethod. Defaults to vmime::headerParseRecoveryMethod::SKIP_LINE. + * @param recoveryMethod is one of vmime::headerParseRecoveryMethod. + * Defaults to vmime::headerParseRecoveryMethod::SKIP_LINE. */ - void setHeaderParseErrorRecoveryMethod(headerParseRecoveryMethod::headerLineError recoveryMethod); + void setHeaderParseErrorRecoveryMethod(const headerParseRecoveryMethod::headerLineError recoveryMethod); /** Return the recovery method when parsing a header encounters an error. * @@ -69,7 +70,6 @@ public: */ headerParseRecoveryMethod::headerLineError getHeaderParseErrorRecoveryMethod() const; - protected: headerParseRecoveryMethod::headerLineError m_headerParseErrorRecovery; diff --git a/src/vmime/path.cpp b/src/vmime/path.cpp index 3f1bc6af..f57d1285 100644 --- a/src/vmime/path.cpp +++ b/src/vmime/path.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,67 +25,69 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { -path::path() -{ +path::path() { + } path::path(const string& localPart, const string& domain) - : m_localPart(localPart), m_domain(domain) -{ + : m_localPart(localPart), + m_domain(domain) { + } path::path(const path& p) - : headerFieldValue(), m_localPart(p.m_localPart), m_domain(p.m_domain) -{ + : headerFieldValue(), + m_localPart(p.m_localPart), + m_domain(p.m_domain) { + } -const string& path::getLocalPart() const -{ - return (m_localPart); +const string& path::getLocalPart() const { + + return m_localPart; } -void path::setLocalPart(const string& localPart) -{ +void path::setLocalPart(const string& localPart) { + m_localPart = localPart; } -const string& path::getDomain() const -{ - return (m_domain); +const string& path::getDomain() const { + + return m_domain; } -void path::setDomain(const string& domain) -{ +void path::setDomain(const string& domain) { + m_domain = domain; } -bool path::operator==(const path& p) const -{ - return (m_localPart == p.m_localPart && - m_domain == p.m_domain); +bool path::operator==(const path& p) const { + + return m_localPart == p.m_localPart && + m_domain == p.m_domain; } -bool path::operator!=(const path& p) const -{ - return (m_localPart != p.m_localPart || - m_domain != p.m_domain); +bool path::operator!=(const path& p) const { + + return m_localPart != p.m_localPart || + m_domain != p.m_domain; } -void path::copyFrom(const component& other) -{ +void path::copyFrom(const component& other) { + const path& p = dynamic_cast (other); m_localPart = p.m_localPart; @@ -93,96 +95,110 @@ void path::copyFrom(const component& other) } -shared_ptr path::clone() const -{ +shared_ptr path::clone() const { + return make_shared (*this); } -path& path::operator=(const path& other) -{ +path& path::operator=(const path& other) { + copyFrom(other); - return (*this); + return *this; } -const std::vector > path::getChildComponents() -{ +const std::vector > path::getChildComponents() { + return std::vector >(); } -void path::parseImpl - (const parsingContext& /* ctx */, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void path::parseImpl( + const parsingContext& /* ctx */, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + size_t pos = position; - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } string addrSpec; - if (pos < end && buffer[pos] == '<') - { + if (pos < end && buffer[pos] == '<') { + // Skip '<' ++pos; - while (pos < end && parserHelpers::isSpace(buffer[pos])) + while (pos < end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } const size_t addrStart = pos; - while (pos < end && buffer[pos] != '>') + while (pos < end && buffer[pos] != '>') { ++pos; + } size_t addrEnd = pos; - while (addrEnd > addrStart && parserHelpers::isSpace(buffer[addrEnd - 1])) + while (addrEnd > addrStart && parserHelpers::isSpace(buffer[addrEnd - 1])) { addrEnd--; + } addrSpec = string(buffer.begin() + addrStart, buffer.begin() + addrEnd); - } - else - { + + } else { + addrSpec = string(buffer.begin() + position, buffer.begin() + end); } const size_t at = addrSpec.find_first_of('@'); - if (at != string::npos) - { + if (at != string::npos) { + m_localPart = string(addrSpec.begin(), addrSpec.begin() + at); m_domain = string(addrSpec.begin() + at + 1, addrSpec.end()); - } - else - { + + } else { + m_localPart.clear(); m_domain = addrSpec; } - if (newPosition != NULL) + if (newPosition) { *newPosition = end; + } } -void path::generateImpl - (const generationContext& /* ctx */, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ - if (m_localPart.empty() && m_domain.empty()) - { +void path::generateImpl( + const generationContext& /* ctx */, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + + if (m_localPart.empty() && m_domain.empty()) { + os << "<>"; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + 2; - } - else - { + } + + } else { + os << "<" << m_localPart << "@" << m_domain << ">"; - if (newLinePos) + if (newLinePos) { *newLinePos = curLinePos + m_localPart.length() + m_domain.length() + 3; + } } } diff --git a/src/vmime/path.hpp b/src/vmime/path.hpp index 2ffa3c22..d63ee674 100644 --- a/src/vmime/path.hpp +++ b/src/vmime/path.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/headerFieldValue.hpp" -namespace vmime -{ +namespace vmime { /** A path: a local part + '@' + a domain. */ +class VMIME_EXPORT path : public headerFieldValue { -class VMIME_EXPORT path : public headerFieldValue -{ public: path(); @@ -85,18 +83,20 @@ protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/plainTextPart.cpp b/src/vmime/plainTextPart.cpp index a9a245f4..859a67cc 100644 --- a/src/vmime/plainTextPart.cpp +++ b/src/vmime/plainTextPart.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,81 +30,90 @@ #include "vmime/emptyContentHandler.hpp" -namespace vmime -{ +namespace vmime { plainTextPart::plainTextPart() - : m_text(make_shared ()) -{ + : m_text(make_shared ()) { + } -plainTextPart::~plainTextPart() -{ +plainTextPart::~plainTextPart() { + } -const mediaType plainTextPart::getType() const -{ - return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); +const mediaType plainTextPart::getType() const { + + return mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN); } -size_t plainTextPart::getPartCount() const -{ - return (1); +size_t plainTextPart::getPartCount() const { + + return 1; } -void plainTextPart::generateIn(const shared_ptr & /* message */, const shared_ptr & parent) const -{ +void plainTextPart::generateIn( + const shared_ptr & /* message */, + const shared_ptr & parent +) const { + // Create a new part shared_ptr part = make_shared (); parent->getBody()->appendPart(part); // Set contents - part->getBody()->setContents(m_text, - mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), m_charset, - encoding::decide(m_text, m_charset, encoding::USAGE_TEXT)); + part->getBody()->setContents( + m_text, + mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), + m_charset, + encoding::decide(m_text, m_charset, encoding::USAGE_TEXT) + ); } -void plainTextPart::parse(const shared_ptr & /* message */, - const shared_ptr & /* parent */, const shared_ptr & textPart) -{ +void plainTextPart::parse( + const shared_ptr & /* message */, + const shared_ptr & /* parent */, + const shared_ptr & textPart +) { + m_text = vmime::clone(textPart->getBody()->getContents()); shared_ptr ctf = textPart->getHeader()->findField (fields::CONTENT_TYPE); - if (ctf && ctf->hasCharset()) + if (ctf && ctf->hasCharset()) { m_charset = ctf->getCharset(); - else + } else { m_charset = charset(); + } } -const charset& plainTextPart::getCharset() const -{ - return (m_charset); +const charset& plainTextPart::getCharset() const { + + return m_charset; } -void plainTextPart::setCharset(const charset& ch) -{ +void plainTextPart::setCharset(const charset& ch) { + m_charset = ch; } -const shared_ptr plainTextPart::getText() const -{ - return (m_text); +const shared_ptr plainTextPart::getText() const{ + + return m_text; } -void plainTextPart::setText(const shared_ptr & text) -{ +void plainTextPart::setText(const shared_ptr & text) { + m_text = vmime::clone(text); } diff --git a/src/vmime/plainTextPart.hpp b/src/vmime/plainTextPart.hpp index 8640dc48..8a0249ee 100644 --- a/src/vmime/plainTextPart.hpp +++ b/src/vmime/plainTextPart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/textPart.hpp" -namespace vmime -{ +namespace vmime { /** Text part of type 'text/plain'. */ +class VMIME_EXPORT plainTextPart : public textPart { -class VMIME_EXPORT plainTextPart : public textPart -{ public: plainTextPart(); @@ -52,8 +50,16 @@ public: size_t getPartCount() const; - void generateIn(const shared_ptr & message, const shared_ptr & parent) const; - void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart); + void generateIn( + const shared_ptr & message, + const shared_ptr & parent + ) const; + + void parse( + const shared_ptr & message, + const shared_ptr & parent, + const shared_ptr & textPart + ); private: diff --git a/src/vmime/platform.cpp b/src/vmime/platform.cpp index 631d5bcf..f2f1e977 100644 --- a/src/vmime/platform.cpp +++ b/src/vmime/platform.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,21 +28,19 @@ #include "vmime/platforms/windows/windowsHandler.hpp" -namespace vmime -{ +namespace vmime { shared_ptr platform::sm_handler; -platform::handler::~handler() -{ +platform::handler::~handler() { + } // static -shared_ptr platform::getDefaultHandler() -{ +shared_ptr platform::getDefaultHandler() { #if VMIME_PLATFORM_IS_WINDOWS return make_shared (); @@ -56,17 +54,17 @@ shared_ptr platform::getDefaultHandler() // static -shared_ptr platform::getHandler() -{ +shared_ptr platform::getHandler() { + // If a custom platform handler is installed, return it - if (sm_handler) + if (sm_handler) { return sm_handler; + } // Else, use the default handler for this platform shared_ptr defaultHandler = getDefaultHandler(); - if (defaultHandler) - { + if (defaultHandler) { sm_handler = defaultHandler; return sm_handler; } diff --git a/src/vmime/platform.hpp b/src/vmime/platform.hpp index ac1834ac..03a7b234 100644 --- a/src/vmime/platform.hpp +++ b/src/vmime/platform.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,23 +43,20 @@ #include "vmime/utility/sync/criticalSection.hpp" -namespace vmime -{ +namespace vmime { /** Allow setting or getting the current platform handler. */ +class VMIME_EXPORT platform { -class VMIME_EXPORT platform -{ public: /** Takes care of all platform-dependent operations. It offers an interface to * access platform-dependent objects: sockets, date/time, file system, etc. */ + class VMIME_EXPORT handler : public object { - class VMIME_EXPORT handler : public object - { public: virtual ~handler(); @@ -142,8 +139,7 @@ public: template - static void setHandler() - { + static void setHandler() { sm_handler = vmime::make_shared (); } @@ -160,4 +156,3 @@ private: #endif // VMIME_PLATFORM_HPP_INCLUDED - diff --git a/src/vmime/platforms/posix/posixChildProcess.cpp b/src/vmime/platforms/posix/posixChildProcess.cpp index c498b7ca..4a9fef39 100644 --- a/src/vmime/platforms/posix/posixChildProcess.cpp +++ b/src/vmime/platforms/posix/posixChildProcess.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,8 +47,8 @@ namespace posix { // posixChildProcessFactory -shared_ptr posixChildProcessFactory::create(const utility::file::path& path) const -{ +shared_ptr posixChildProcessFactory::create(const utility::file::path& path) const { + return make_shared (path); } @@ -60,29 +60,28 @@ shared_ptr posixChildProcessFactory::create(const utilit // getPosixSignalMessage // Returns the name of a POSIX signal. -static const string getPosixSignalMessage(const int num) -{ - switch (num) - { - case SIGHUP: return "SIGHUP"; - case SIGINT: return "SIGINT"; - case SIGQUIT: return "SIGQUIT"; - case SIGILL: return "SIGILL"; - case SIGABRT: return "SIGABRT"; - case SIGFPE: return "SIGFPE"; - case SIGKILL: return "SIGKILL"; - case SIGSEGV: return "SIGSEGV"; - case SIGPIPE: return "SIGPIPE"; - case SIGALRM: return "SIGALRM"; - case SIGTERM: return "SIGTERM"; - case SIGUSR1: return "SIGUSR1"; - case SIGUSR2: return "SIGUSR2"; - case SIGCHLD: return "SIGCHLD"; - case SIGCONT: return "SIGCONT"; - case SIGSTOP: return "SIGSTOP"; - case SIGTSTP: return "SIGTSTP"; - case SIGTTIN: return "SIGTTIN"; - case SIGTTOU: return "SIGTTOU"; +static const string getPosixSignalMessage(const int num) { + + switch (num) { + case SIGHUP: return "SIGHUP"; + case SIGINT: return "SIGINT"; + case SIGQUIT: return "SIGQUIT"; + case SIGILL: return "SIGILL"; + case SIGABRT: return "SIGABRT"; + case SIGFPE: return "SIGFPE"; + case SIGKILL: return "SIGKILL"; + case SIGSEGV: return "SIGSEGV"; + case SIGPIPE: return "SIGPIPE"; + case SIGALRM: return "SIGALRM"; + case SIGTERM: return "SIGTERM"; + case SIGUSR1: return "SIGUSR1"; + case SIGUSR2: return "SIGUSR2"; + case SIGCHLD: return "SIGCHLD"; + case SIGCONT: return "SIGCONT"; + case SIGSTOP: return "SIGSTOP"; + case SIGTSTP: return "SIGTSTP"; + case SIGTTIN: return "SIGTTIN"; + case SIGTTOU: return "SIGTTOU"; } return "(unknown)"; @@ -92,8 +91,8 @@ static const string getPosixSignalMessage(const int num) // getPosixErrorMessage // Returns a message corresponding to an error code. -static const string getPosixErrorMessage(const int num) -{ +static const string getPosixErrorMessage(const int num) { + #ifdef strerror_r char res[256]; res[0] = '\0'; @@ -104,31 +103,31 @@ static const string getPosixErrorMessage(const int num) #else return string(strerror(num)); #endif + } // Output stream adapter for POSIX pipe -class outputStreamPosixPipeAdapter : public utility::outputStream -{ +class outputStreamPosixPipeAdapter : public utility::outputStream { + public: outputStreamPosixPipeAdapter(const int desc) - : m_desc(desc) - { + : m_desc(desc) { + } - void flush() - { + void flush() { + ::fsync(m_desc); } protected: - void writeImpl(const byte_t* const data, const size_t count) - { - if (::write(m_desc, data, count) == -1) - { + void writeImpl(const byte_t* const data, const size_t count) { + + if (::write(m_desc, data, count) == -1) { const string errorMsg = getPosixErrorMessage(errno); throw exceptions::system_error(errorMsg); } @@ -142,27 +141,26 @@ private: // Input stream adapter for POSIX pipe -class inputStreamPosixPipeAdapter : public utility::inputStream -{ +class inputStreamPosixPipeAdapter : public utility::inputStream { + public: inputStreamPosixPipeAdapter(const int desc) - : m_desc(desc) - { + : m_desc(desc) { } - bool eof() const - { - return (m_eof); + bool eof() const { + + return m_eof; } - void reset() - { + void reset() { + // Do nothing: unsupported } - size_t skip(const size_t count) - { + size_t skip(const size_t count) { + // TODO: not tested byte_t buffer[4096]; @@ -170,10 +168,9 @@ public: ssize_t bytesRead = 0; while ((bytesRead = ::read(m_desc, buffer, - std::min(sizeof(buffer), count - bytesSkipped))) != 0) - { - if (bytesRead == -1) - { + std::min(sizeof(buffer), count - bytesSkipped))) != 0) { + + if (bytesRead == -1) { const string errorMsg = getPosixErrorMessage(errno); throw exceptions::system_error(errorMsg); } @@ -184,12 +181,11 @@ public: return static_cast (bytesSkipped); } - size_t read(byte_t* const data, const size_t count) - { + size_t read(byte_t* const data, const size_t count) { + ssize_t bytesRead = 0; - if ((bytesRead = ::read(m_desc, data, count)) == -1) - { + if ((bytesRead = ::read(m_desc, data, count)) == -1) { const string errorMsg = getPosixErrorMessage(errno); throw exceptions::system_error(errorMsg); } @@ -214,9 +210,13 @@ private: // posixChildProcess posixChildProcess::posixChildProcess(const utility::file::path& path) - : m_processPath(path), m_started(false), - m_stdIn(null), m_stdOut(null), m_pid(0), m_argArray(NULL) -{ + : m_processPath(path), + m_started(false), + m_stdIn(null), + m_stdOut(null), + m_pid(0), + m_argArray(NULL) { + m_pipe[0] = 0; m_pipe[1] = 0; @@ -224,18 +224,21 @@ posixChildProcess::posixChildProcess(const utility::file::path& path) } -posixChildProcess::~posixChildProcess() -{ - if (m_started) +posixChildProcess::~posixChildProcess() { + + if (m_started) { sigprocmask(SIG_SETMASK, &m_oldProcMask, NULL); + } - if (m_pipe[0] != 0) + if (m_pipe[0] != 0) { close(m_pipe[0]); + } - if (m_pipe[1] != 0) + if (m_pipe[1] != 0) { close(m_pipe[1]); + } - delete [] (m_argArray); + delete [] m_argArray; } @@ -245,10 +248,11 @@ posixChildProcess::~posixChildProcess() // Original authors: Dan Winship // Copyright 2000 Ximian, Inc. (www.ximian.com) -void posixChildProcess::start(const std::vector & args, const int flags) -{ - if (m_started) +void posixChildProcess::start(const std::vector & args, const int flags) { + + if (m_started) { return; + } // Construct C-style argument array const char** argv = new const char*[args.size() + 2]; @@ -259,14 +263,14 @@ void posixChildProcess::start(const std::vector & args, const int flags) argv[0] = m_processPath.getLastComponent().getBuffer().c_str(); argv[args.size() + 1] = NULL; - for (unsigned int i = 0 ; i < m_argVector.size() ; ++i) + for (unsigned int i = 0 ; i < m_argVector.size() ; ++i) { argv[i + 1] = m_argVector[i].c_str(); + } // Create a pipe to communicate with the child process int fd[2]; - if (pipe(fd) == -1) - { + if (pipe(fd) == -1) { throw exceptions::system_error(getPosixErrorMessage(errno)); } @@ -284,8 +288,8 @@ void posixChildProcess::start(const std::vector & args, const int flags) // Spawn process const pid_t pid = fork(); - if (pid == -1) // error - { + if (pid == -1) { // error + const string errorMsg = getPosixErrorMessage(errno); sigprocmask(SIG_SETMASK, &m_oldProcMask, NULL); @@ -294,45 +298,47 @@ void posixChildProcess::start(const std::vector & args, const int flags) close(fd[1]); throw exceptions::system_error(errorMsg); - } - else if (pid == 0) // child process - { - if (flags & FLAG_REDIRECT_STDIN) - dup2(fd[0], STDIN_FILENO); - else - close(fd[0]); - if (flags & FLAG_REDIRECT_STDOUT) + } else if (pid == 0) { // child process + + if (flags & FLAG_REDIRECT_STDIN) { + dup2(fd[0], STDIN_FILENO); + } else { + close(fd[0]); + } + + if (flags & FLAG_REDIRECT_STDOUT) { dup2(fd[1], STDOUT_FILENO); - else + } else { close(fd[1]); + } posixFileSystemFactory* pfsf = new posixFileSystemFactory(); const string path = pfsf->pathToString(m_processPath); - delete (pfsf); + delete pfsf; execv(path.c_str(), const_cast (argv)); _exit(255); } - if (flags & FLAG_REDIRECT_STDIN) - { + if (flags & FLAG_REDIRECT_STDIN) { + m_stdIn = make_shared (m_pipe[1]); - } - else - { + + } else { + close(m_pipe[1]); m_pipe[1] = 0; } - if (flags & FLAG_REDIRECT_STDOUT) - { + if (flags & FLAG_REDIRECT_STDOUT) { + m_stdOut = make_shared (m_pipe[0]); - } - else - { + + } else { + close(m_pipe[0]); m_pipe[0] = 0; } @@ -342,48 +348,48 @@ void posixChildProcess::start(const std::vector & args, const int flags) } -shared_ptr posixChildProcess::getStdIn() -{ - return (m_stdIn); +shared_ptr posixChildProcess::getStdIn() { + + return m_stdIn; } -shared_ptr posixChildProcess::getStdOut() -{ - return (m_stdOut); +shared_ptr posixChildProcess::getStdOut() { + + return m_stdOut; } -void posixChildProcess::waitForFinish() -{ +void posixChildProcess::waitForFinish() { + // Close stdin pipe - if (m_pipe[1] != 0) - { + if (m_pipe[1] != 0) { close(m_pipe[1]); m_pipe[1] = 0; } int wstat; - while (waitpid(m_pid, &wstat, 0) == -1 && errno == EINTR) + while (waitpid(m_pid, &wstat, 0) == -1 && errno == EINTR) { ; + } + + if (!WIFEXITED(wstat)) { - if (!WIFEXITED(wstat)) - { throw exceptions::system_error("Process exited with signal " + getPosixSignalMessage(WTERMSIG(wstat))); - } - else if (WEXITSTATUS(wstat) != 0) - { - if (WEXITSTATUS(wstat) == 255) - { + + } else if (WEXITSTATUS(wstat) != 0) { + + if (WEXITSTATUS(wstat) == 255) { + scoped_ptr pfsf(new posixFileSystemFactory()); throw exceptions::system_error("Could not execute '" + pfsf->pathToString(m_processPath) + "'"); - } - else - { + + } else { + std::ostringstream oss; oss.imbue(std::locale::classic()); diff --git a/src/vmime/platforms/posix/posixChildProcess.hpp b/src/vmime/platforms/posix/posixChildProcess.hpp index 33f166f2..b831e8bb 100644 --- a/src/vmime/platforms/posix/posixChildProcess.hpp +++ b/src/vmime/platforms/posix/posixChildProcess.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace platforms { namespace posix { -class posixChildProcess : public utility::childProcess -{ +class posixChildProcess : public utility::childProcess { + public: posixChildProcess(const utility::file::path& path); @@ -73,8 +73,8 @@ private: }; -class posixChildProcessFactory : public utility::childProcessFactory -{ +class posixChildProcessFactory : public utility::childProcessFactory { + public: shared_ptr create(const utility::file::path& path) const; diff --git a/src/vmime/platforms/posix/posixCriticalSection.cpp b/src/vmime/platforms/posix/posixCriticalSection.cpp index fb2c469c..2f25cfa4 100644 --- a/src/vmime/platforms/posix/posixCriticalSection.cpp +++ b/src/vmime/platforms/posix/posixCriticalSection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,26 +35,26 @@ namespace platforms { namespace posix { -posixCriticalSection::posixCriticalSection() -{ +posixCriticalSection::posixCriticalSection() { + pthread_mutex_init(&m_cs, NULL); } -posixCriticalSection::~posixCriticalSection() -{ +posixCriticalSection::~posixCriticalSection() { + pthread_mutex_destroy(&m_cs); } -void posixCriticalSection::lock() -{ +void posixCriticalSection::lock() { + pthread_mutex_lock(&m_cs); } -void posixCriticalSection::unlock() -{ +void posixCriticalSection::unlock() { + pthread_mutex_unlock(&m_cs); } diff --git a/src/vmime/platforms/posix/posixCriticalSection.hpp b/src/vmime/platforms/posix/posixCriticalSection.hpp index 150799cd..9a4bed53 100644 --- a/src/vmime/platforms/posix/posixCriticalSection.hpp +++ b/src/vmime/platforms/posix/posixCriticalSection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace platforms { namespace posix { -class posixCriticalSection : public utility::sync::criticalSection -{ +class posixCriticalSection : public utility::sync::criticalSection { + public: posixCriticalSection(); diff --git a/src/vmime/platforms/posix/posixFile.cpp b/src/vmime/platforms/posix/posixFile.cpp index ea699ac4..9773b3a0 100644 --- a/src/vmime/platforms/posix/posixFile.cpp +++ b/src/vmime/platforms/posix/posixFile.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -53,61 +53,71 @@ namespace posix { // posixFileIterator // -posixFileIterator::posixFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath) - : m_path(path), m_nativePath(nativePath), m_dir(NULL), m_dirEntry(NULL) -{ - if ((m_dir = ::opendir(m_nativePath.c_str())) == NULL) +posixFileIterator::posixFileIterator( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath), + m_dir(NULL), + m_dirEntry(NULL) { + + if ((m_dir = ::opendir(m_nativePath.c_str())) == NULL) { posixFileSystemFactory::reportError(path, errno); + } getNextElement(); } -posixFileIterator::~posixFileIterator() -{ - if (m_dir != NULL) - { - if (::closedir(m_dir) == -1) +posixFileIterator::~posixFileIterator() { + + if (m_dir) { + + if (::closedir(m_dir) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } } } -bool posixFileIterator::hasMoreElements() const -{ +bool posixFileIterator::hasMoreElements() const { + return (m_dirEntry != NULL); } -shared_ptr posixFileIterator::nextElement() -{ - shared_ptr file = make_shared - (m_path / vmime::utility::file::path::component(m_dirEntry->d_name)); +shared_ptr posixFileIterator::nextElement() { + + shared_ptr file = make_shared ( + m_path / vmime::utility::file::path::component(m_dirEntry->d_name) + ); getNextElement(); - return (file); + return file; } -void posixFileIterator::getNextElement() -{ +void posixFileIterator::getNextElement() { + errno = 0; - while ((m_dirEntry = ::readdir(m_dir)) != NULL) - { + while ((m_dirEntry = ::readdir(m_dir)) != NULL) { + const char* name = m_dirEntry->d_name; const size_t len = ::strlen(name); if (!(len == 1 && name[0] == '.') && - !(len == 2 && name[0] == '.' && name[1] == '.')) - { + !(len == 2 && name[0] == '.' && name[1] == '.')) { + break; } } - if (errno) + if (errno) { posixFileSystemFactory::reportError(m_path, errno); + } } @@ -116,38 +126,45 @@ void posixFileIterator::getNextElement() // posixFileWriterOutputStream // -posixFileWriterOutputStream::posixFileWriterOutputStream(const vmime::utility::file::path& path, const int fd) - : m_path(path), m_fd(fd) -{ +posixFileWriterOutputStream::posixFileWriterOutputStream( + const vmime::utility::file::path& path, + const int fd +) + : m_path(path), + m_fd(fd) { + } -posixFileWriterOutputStream::~posixFileWriterOutputStream() -{ +posixFileWriterOutputStream::~posixFileWriterOutputStream() { + ::close(m_fd); } -void posixFileWriterOutputStream::writeImpl - (const byte_t* const data, const size_t count) -{ +void posixFileWriterOutputStream::writeImpl( + const byte_t* const data, + const size_t count +) { + const byte_t* array = data; size_t size = count; - while (1) - { + while (1) { + ssize_t ret = ::write(m_fd, array, size); - if (ret == -1) - { - if (errno == EINTR) + if (ret == -1) { + + if (errno == EINTR) { continue; + } posixFileSystemFactory::reportError(m_path, errno); break; - } - else if (size_t(ret) < size) - { + + } else if (size_t(ret) < size) { + array += ret; size -= ret; } @@ -157,10 +174,11 @@ void posixFileWriterOutputStream::writeImpl } -void posixFileWriterOutputStream::flush() -{ - if (::fsync(m_fd) == -1) +void posixFileWriterOutputStream::flush() { + + if (::fsync(m_fd) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } } @@ -169,82 +187,97 @@ void posixFileWriterOutputStream::flush() // posixFileReaderInputStream // -posixFileReaderInputStream::posixFileReaderInputStream(const vmime::utility::file::path& path, const int fd) - : m_path(path), m_fd(fd), m_eof(false) -{ +posixFileReaderInputStream::posixFileReaderInputStream( + const vmime::utility::file::path& path, + const int fd +) + : m_path(path), + m_fd(fd), + m_eof(false) { + } -posixFileReaderInputStream::~posixFileReaderInputStream() -{ - if (::close(m_fd) == -1) +posixFileReaderInputStream::~posixFileReaderInputStream() { + + if (::close(m_fd) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } } -bool posixFileReaderInputStream::eof() const -{ - return (m_eof); +bool posixFileReaderInputStream::eof() const { + + return m_eof; } -void posixFileReaderInputStream::reset() -{ - if (::lseek(m_fd, 0, SEEK_SET) == off_t(-1)) +void posixFileReaderInputStream::reset() { + + if (::lseek(m_fd, 0, SEEK_SET) == off_t(-1)) { posixFileSystemFactory::reportError(m_path, errno); + } m_eof = false; } -size_t posixFileReaderInputStream::read - (byte_t* const data, const size_t count) -{ +size_t posixFileReaderInputStream::read( + byte_t* const data, + const size_t count +) { + ssize_t c = 0; - if ((c = ::read(m_fd, data, count)) == -1) + if ((c = ::read(m_fd, data, count)) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } - if (c == 0 && count != 0) + if (c == 0 && count != 0) { m_eof = true; + } return static_cast (c); } -size_t posixFileReaderInputStream::skip(const size_t count) -{ +size_t posixFileReaderInputStream::skip(const size_t count) { + const off_t curPos = ::lseek(m_fd, 0, SEEK_CUR); - if (curPos == off_t(-1)) + if (curPos == off_t(-1)) { posixFileSystemFactory::reportError(m_path, errno); + } const off_t newPos = ::lseek(m_fd, count, SEEK_CUR); - if (newPos == off_t(-1)) + if (newPos == off_t(-1)) { posixFileSystemFactory::reportError(m_path, errno); + } return static_cast (newPos - curPos); } -size_t posixFileReaderInputStream::getPosition() const -{ +size_t posixFileReaderInputStream::getPosition() const { + const off_t curPos = ::lseek(m_fd, 0, SEEK_CUR); - if (curPos == off_t(-1)) + if (curPos == off_t(-1)) { posixFileSystemFactory::reportError(m_path, errno); + } return static_cast (curPos); } -void posixFileReaderInputStream::seek(const size_t pos) -{ +void posixFileReaderInputStream::seek(const size_t pos) { + const off_t newPos = ::lseek(m_fd, pos, SEEK_SET); - if (newPos == off_t(-1)) + if (newPos == off_t(-1)) { posixFileSystemFactory::reportError(m_path, errno); + } } @@ -253,18 +286,23 @@ void posixFileReaderInputStream::seek(const size_t pos) // posixFileWriter // -posixFileWriter::posixFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath) - : m_path(path), m_nativePath(nativePath) -{ +posixFileWriter::posixFileWriter( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath) { + } -shared_ptr posixFileWriter::getOutputStream() -{ +shared_ptr posixFileWriter::getOutputStream() { + int fd = 0; - if ((fd = ::open(m_nativePath.c_str(), O_WRONLY, 0660)) == -1) + if ((fd = ::open(m_nativePath.c_str(), O_WRONLY, 0660)) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } return make_shared (m_path, fd); } @@ -275,18 +313,23 @@ shared_ptr posixFileWriter::getOutputStream() // posixFileReader // -posixFileReader::posixFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath) - : m_path(path), m_nativePath(nativePath) -{ +posixFileReader::posixFileReader( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath) { + } -shared_ptr posixFileReader::getInputStream() -{ +shared_ptr posixFileReader::getInputStream() { + int fd = 0; - if ((fd = ::open(m_nativePath.c_str(), O_RDONLY, 0640)) == -1) + if ((fd = ::open(m_nativePath.c_str(), O_RDONLY, 0640)) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } return make_shared (m_path, fd); } @@ -298,40 +341,45 @@ shared_ptr posixFileReader::getInputStream() // posixFile::posixFile(const vmime::utility::file::path& path) - : m_path(path), m_nativePath(posixFileSystemFactory::pathToStringImpl(path)) -{ + : m_path(path), + m_nativePath(posixFileSystemFactory::pathToStringImpl(path)) { + } -void posixFile::createFile() -{ +void posixFile::createFile() { + int fd = 0; - if ((fd = ::open(m_nativePath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660)) == -1) + if ((fd = ::open(m_nativePath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660)) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } - if (::fsync(fd) == -1) + if (::fsync(fd) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } - if (::close(fd) == -1) + if (::close(fd) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } } -void posixFile::createDirectory(const bool createAll) -{ +void posixFile::createDirectory(const bool createAll) { + createDirectoryImpl(m_path, m_path, createAll); } -bool posixFile::isFile() const -{ +bool posixFile::isFile() const { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) - { - if (errno == ENOENT) + if (::stat(m_nativePath.c_str(), &buf) == -1) { + + if (errno == ENOENT) { return false; + } posixFileSystemFactory::reportError(m_path, errno); return false; @@ -341,14 +389,15 @@ bool posixFile::isFile() const } -bool posixFile::isDirectory() const -{ +bool posixFile::isDirectory() const { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) - { - if (errno == ENOENT) + if (::stat(m_nativePath.c_str(), &buf) == -1) { + + if (errno == ENOENT) { return false; + } posixFileSystemFactory::reportError(m_path, errno); return false; @@ -358,149 +407,165 @@ bool posixFile::isDirectory() const } -bool posixFile::canRead() const -{ +bool posixFile::canRead() const { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) - { - if (errno == ENOENT) + if (::stat(m_nativePath.c_str(), &buf) == -1) { + + if (errno == ENOENT) { return false; + } posixFileSystemFactory::reportError(m_path, errno); return false; } - return S_ISREG(buf.st_mode) && - ::access(m_nativePath.c_str(), R_OK | F_OK) == 0; + return S_ISREG(buf.st_mode) + && ::access(m_nativePath.c_str(), R_OK | F_OK) == 0; } -bool posixFile::canWrite() const -{ +bool posixFile::canWrite() const { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) - { - if (errno == ENOENT) + if (::stat(m_nativePath.c_str(), &buf) == -1) { + + if (errno == ENOENT) { return false; + } posixFileSystemFactory::reportError(m_path, errno); return false; } - return S_ISREG(buf.st_mode) && - ::access(m_nativePath.c_str(), W_OK | F_OK) == 0; + return S_ISREG(buf.st_mode) + && ::access(m_nativePath.c_str(), W_OK | F_OK) == 0; } -posixFile::length_type posixFile::getLength() -{ +posixFile::length_type posixFile::getLength() { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) + if (::stat(m_nativePath.c_str(), &buf) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } return static_cast (buf.st_size); } -const posixFile::path& posixFile::getFullPath() const -{ - return (m_path); +const posixFile::path& posixFile::getFullPath() const { + + return m_path; } -bool posixFile::exists() const -{ +bool posixFile::exists() const { + struct stat buf; - return (::stat(m_nativePath.c_str(), &buf) == 0); + return ::stat(m_nativePath.c_str(), &buf) == 0; } -shared_ptr posixFile::getParent() const -{ - if (m_path.isEmpty()) +shared_ptr posixFile::getParent() const { + + if (m_path.isEmpty()) { return null; - else + } else { return make_shared (m_path.getParent()); + } } -void posixFile::rename(const path& newName) -{ +void posixFile::rename(const path& newName) { + const vmime::string newNativePath = posixFileSystemFactory::pathToStringImpl(newName); posixFile dest(newName); - if (isDirectory()) + if (isDirectory()) { dest.createDirectory(); - else + } else { dest.createFile(); + } - if (::rename(m_nativePath.c_str(), newNativePath.c_str()) == -1) + if (::rename(m_nativePath.c_str(), newNativePath.c_str()) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } m_path = newName; m_nativePath = newNativePath; } -void posixFile::remove() -{ +void posixFile::remove() { + struct stat buf; - if (::stat(m_nativePath.c_str(), &buf) == -1) + if (::stat(m_nativePath.c_str(), &buf) == -1) { posixFileSystemFactory::reportError(m_path, errno); - - if (S_ISDIR(buf.st_mode)) - { - if (::rmdir(m_nativePath.c_str()) == -1) - posixFileSystemFactory::reportError(m_path, errno); } - else if (S_ISREG(buf.st_mode)) - { - if (::unlink(m_nativePath.c_str()) == -1) + + if (S_ISDIR(buf.st_mode)) { + + if (::rmdir(m_nativePath.c_str()) == -1) { posixFileSystemFactory::reportError(m_path, errno); + } + + } else if (S_ISREG(buf.st_mode)) { + + if (::unlink(m_nativePath.c_str()) == -1) { + posixFileSystemFactory::reportError(m_path, errno); + } } } -shared_ptr posixFile::getFileWriter() -{ +shared_ptr posixFile::getFileWriter() { + return make_shared (m_path, m_nativePath); } -shared_ptr posixFile::getFileReader() -{ +shared_ptr posixFile::getFileReader() { + return make_shared (m_path, m_nativePath); } -shared_ptr posixFile::getFiles() const -{ - if (!isDirectory()) +shared_ptr posixFile::getFiles() const { + + if (!isDirectory()) { throw vmime::exceptions::not_a_directory(m_path); + } return make_shared (m_path, m_nativePath); } -void posixFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, - const vmime::utility::file::path& path, const bool recursive) -{ +void posixFile::createDirectoryImpl( + const vmime::utility::file::path& fullPath, + const vmime::utility::file::path& path, + const bool recursive +) { + const vmime::string nativePath = posixFileSystemFactory::pathToStringImpl(path); struct stat buf; - if (::stat(nativePath.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode)) + if (::stat(nativePath.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode)) { return; + } - if (!path.isEmpty() && recursive) + if (!path.isEmpty() && recursive) { createDirectoryImpl(fullPath, path.getParent(), true); + } - if (::mkdir(nativePath.c_str(), 0750) == -1) + if (::mkdir(nativePath.c_str(), 0750) == -1) { posixFileSystemFactory::reportError(fullPath, errno); + } } @@ -509,125 +574,139 @@ void posixFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, // posixFileSystemFactory // -shared_ptr posixFileSystemFactory::create(const vmime::utility::file::path& path) const -{ +shared_ptr posixFileSystemFactory::create( + const vmime::utility::file::path& path +) const { + return make_shared (path); } -const vmime::utility::file::path posixFileSystemFactory::stringToPath(const vmime::string& str) const -{ - return (stringToPathImpl(str)); +const vmime::utility::file::path posixFileSystemFactory::stringToPath( + const vmime::string& str +) const { + + return stringToPathImpl(str); } -const vmime::string posixFileSystemFactory::pathToString(const vmime::utility::file::path& path) const -{ - return (pathToStringImpl(path)); +const vmime::string posixFileSystemFactory::pathToString( + const vmime::utility::file::path& path +) const { + + return pathToStringImpl(path); } -const vmime::utility::file::path posixFileSystemFactory::stringToPathImpl(const vmime::string& str) -{ +const vmime::utility::file::path posixFileSystemFactory::stringToPathImpl( + const vmime::string& str +) { + vmime::size_t offset = 0; vmime::size_t prev = 0; vmime::utility::file::path path; - while ((offset = str.find_first_of("/", offset)) != vmime::string::npos) - { - if (offset != prev) - { - path.appendComponent - (vmime::utility::file::path::component - (vmime::string(str.begin() + prev, str.begin() + offset))); + while ((offset = str.find_first_of("/", offset)) != vmime::string::npos) { + + if (offset != prev) { + + path.appendComponent( + vmime::utility::file::path::component( + vmime::string(str.begin() + prev, str.begin() + offset) + ) + ); } prev = offset + 1; offset++; } - if (prev < str.length()) - { - path.appendComponent - (vmime::utility::file::path::component - (vmime::string(str.begin() + prev, str.end()))); + if (prev < str.length()) { + + path.appendComponent( + vmime::utility::file::path::component( + vmime::string(str.begin() + prev, str.end()) + ) + ); } - return (path); + return path; } -const vmime::string posixFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path) -{ +const vmime::string posixFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path) { + vmime::string native = "/"; - for (size_t i = 0 ; i < path.getSize() ; ++i) - { - if (i > 0) + for (size_t i = 0 ; i < path.getSize() ; ++i) { + + if (i > 0) { native += "/"; + } native += path[i].getBuffer(); } - return (native); + return native; } -bool posixFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const -{ - return (comp.getBuffer().find_first_of("/*") == vmime::string::npos); +bool posixFileSystemFactory::isValidPathComponent( + const vmime::utility::file::path::component& comp +) const { + + return comp.getBuffer().find_first_of("/*") == vmime::string::npos; } -bool posixFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const -{ - for (size_t i = 0 ; i < path.getSize() ; ++i) - { - if (!isValidPathComponent(path[i])) +bool posixFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const { + + for (size_t i = 0 ; i < path.getSize() ; ++i) { + + if (!isValidPathComponent(path[i])) { return false; + } } return true; } -void posixFileSystemFactory::reportError(const vmime::utility::path& path, const int err) -{ +void posixFileSystemFactory::reportError(const vmime::utility::path& path, const int err) { + vmime::string desc; - switch (err) - { - case EEXIST: desc = "EEXIST: file already exists."; break; - case EISDIR: desc = "EISDIR: path refers to a directory."; break; - case EACCES: desc = "EACCES: permission denied"; break; - case ENAMETOOLONG: desc = "ENAMETOOLONG: path too long."; break; - case ENOENT: desc = "ENOENT: a directory in the path does not exist."; break; - case ENOTDIR: desc = "ENOTDIR: path is not a directory."; break; - case EROFS: desc = "EROFS: read-only filesystem."; break; - case ELOOP: desc = "ELOOP: too many symbolic links."; break; - case ENOSPC: desc = "ENOSPC: no space left on device."; break; - case ENOMEM: desc = "ENOMEM: insufficient kernel memory."; break; - case EMFILE: desc = "ENFILE: limit on number of files open by the process has been reached."; break; - case ENFILE: desc = "ENFILE: limit on number of files open on the system has been reached."; break; + switch (err) { + case EEXIST: desc = "EEXIST: file already exists."; break; + case EISDIR: desc = "EISDIR: path refers to a directory."; break; + case EACCES: desc = "EACCES: permission denied"; break; + case ENAMETOOLONG: desc = "ENAMETOOLONG: path too long."; break; + case ENOENT: desc = "ENOENT: a directory in the path does not exist."; break; + case ENOTDIR: desc = "ENOTDIR: path is not a directory."; break; + case EROFS: desc = "EROFS: read-only filesystem."; break; + case ELOOP: desc = "ELOOP: too many symbolic links."; break; + case ENOSPC: desc = "ENOSPC: no space left on device."; break; + case ENOMEM: desc = "ENOMEM: insufficient kernel memory."; break; + case EMFILE: desc = "ENFILE: limit on number of files open by the process has been reached."; break; + case ENFILE: desc = "ENFILE: limit on number of files open on the system has been reached."; break; #ifndef AIX - case ENOTEMPTY: desc = "ENOTEMPTY: directory is not empty."; break; + case ENOTEMPTY: desc = "ENOTEMPTY: directory is not empty."; break; #endif - default: + default: - std::ostringstream oss; - oss << ::strerror(err) << "."; + std::ostringstream oss; + oss << ::strerror(err) << "."; - desc = oss.str(); - break; + desc = oss.str(); + break; } throw vmime::exceptions::filesystem_exception(desc, path); } - } // posix } // platforms } // vmime diff --git a/src/vmime/platforms/posix/posixFile.hpp b/src/vmime/platforms/posix/posixFile.hpp index 20a56699..d1fda9e8 100644 --- a/src/vmime/platforms/posix/posixFile.hpp +++ b/src/vmime/platforms/posix/posixFile.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace platforms { namespace posix { -class posixFileWriterOutputStream : public vmime::utility::outputStream -{ +class posixFileWriterOutputStream : public vmime::utility::outputStream { + public: posixFileWriterOutputStream(const vmime::utility::file::path& path, const int fd); @@ -64,8 +64,8 @@ private: -class posixFileReaderInputStream : public vmime::utility::seekableInputStream -{ +class posixFileReaderInputStream : public vmime::utility::seekableInputStream { + public: posixFileReaderInputStream(const vmime::utility::file::path& path, const int fd); @@ -92,8 +92,8 @@ private: -class posixFileWriter : public vmime::utility::fileWriter -{ +class posixFileWriter : public vmime::utility::fileWriter { + public: posixFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -108,8 +108,8 @@ private: -class posixFileReader : public vmime::utility::fileReader -{ +class posixFileReader : public vmime::utility::fileReader { + public: posixFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -124,8 +124,8 @@ private: -class posixFileIterator : public vmime::utility::fileIterator -{ +class posixFileIterator : public vmime::utility::fileIterator { + public: posixFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -147,8 +147,8 @@ private: -class posixFile : public vmime::utility::file -{ +class posixFile : public vmime::utility::file { + public: posixFile(const vmime::utility::file::path& path); @@ -181,7 +181,11 @@ public: private: - static void createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive = false); + static void createDirectoryImpl( + const vmime::utility::file::path& fullPath, + const vmime::utility::file::path& path, + const bool recursive = false + ); private: @@ -191,8 +195,8 @@ private: -class posixFileSystemFactory : public vmime::utility::fileSystemFactory -{ +class posixFileSystemFactory : public vmime::utility::fileSystemFactory { + public: shared_ptr create(const vmime::utility::file::path& path) const; diff --git a/src/vmime/platforms/posix/posixHandler.cpp b/src/vmime/platforms/posix/posixHandler.cpp index e0263b2b..20c0f342 100644 --- a/src/vmime/platforms/posix/posixHandler.cpp +++ b/src/vmime/platforms/posix/posixHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -68,27 +68,29 @@ #if VMIME_HAVE_PTHREAD -namespace -{ +namespace { + // This construction ensures mutex will be initialized in compile-time // and will be available any time in the runtime. pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; // Helper lock, to be exception safe all the time. - class PLockHelper - { + class PLockHelper { + public: - PLockHelper() - { - if (pthread_mutex_lock(&g_mutex) != 0) + PLockHelper() { + + if (pthread_mutex_lock(&g_mutex) != 0) { assert(!"unable to lock mutex - thread safety's void"); + } } - ~PLockHelper() - { - if (pthread_mutex_unlock(&g_mutex) != 0) + ~PLockHelper() { + + if (pthread_mutex_unlock(&g_mutex) != 0) { assert(!"unable to unlock mutex - application's dead..."); + } } private: @@ -108,8 +110,8 @@ namespace platforms { namespace posix { -posixHandler::posixHandler() -{ +posixHandler::posixHandler() { + #if VMIME_HAVE_MESSAGING_FEATURES m_socketFactory = make_shared (); #endif @@ -117,22 +119,23 @@ posixHandler::posixHandler() m_fileSysFactory = make_shared (); m_childProcFactory = make_shared (); #endif + } -posixHandler::~posixHandler() -{ +posixHandler::~posixHandler() { + } -unsigned long posixHandler::getUnixTime() const -{ +unsigned long posixHandler::getUnixTime() const { + return static_cast (::time(NULL)); } -const vmime::datetime posixHandler::getCurrentLocalTime() const -{ +const vmime::datetime posixHandler::getCurrentLocalTime() const { + const time_t t(::time(NULL)); // Get the local time @@ -168,20 +171,20 @@ const vmime::datetime posixHandler::getCurrentLocalTime() const } -const vmime::charset posixHandler::getLocalCharset() const -{ +const vmime::charset posixHandler::getLocalCharset() const { + const PLockHelper lock; return vmime::charset(::nl_langinfo(CODESET)); } -static inline bool isAcceptableHostname(const vmime::string& str) -{ +static inline bool isAcceptableHostname(const vmime::string& str) { + // At least, try to find something better than "localhost" if (utility::stringUtils::isStringEqualNoCase(str, "localhost", 9) || - utility::stringUtils::isStringEqualNoCase(str, "localhost.localdomain", 21)) - { + utility::stringUtils::isStringEqualNoCase(str, "localhost.localdomain", 21)) { + return false; } @@ -190,8 +193,8 @@ static inline bool isAcceptableHostname(const vmime::string& str) } -const vmime::string posixHandler::getHostName() const -{ +const vmime::string posixHandler::getHostName() const { + // Try to get official canonical name of this host struct addrinfo hints; memset(&hints, 0, sizeof hints); @@ -201,17 +204,16 @@ const vmime::string posixHandler::getHostName() const struct addrinfo* info; - if (getaddrinfo(NULL, "http", &hints, &info) == 0) - { + if (getaddrinfo(NULL, "http", &hints, &info) == 0) { + // First, try to get a Fully-Qualified Domain Name (FQDN) - for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) - { - if (p->ai_canonname) - { + for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) { + + if (p->ai_canonname) { + const string hn(p->ai_canonname); - if (utility::stringUtils::isValidFQDN(hn)) - { + if (utility::stringUtils::isValidFQDN(hn)) { freeaddrinfo(info); return hn; } @@ -219,14 +221,13 @@ const vmime::string posixHandler::getHostName() const } // Then, try to find an acceptable host name - for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) - { - if (p->ai_canonname) - { + for (struct addrinfo* p = info ; p != NULL ; p = p->ai_next) { + + if (p->ai_canonname) { + const string hn(p->ai_canonname); - if (isAcceptableHostname(hn)) - { + if (isAcceptableHostname(hn)) { freeaddrinfo(info); return hn; } @@ -241,21 +242,22 @@ const vmime::string posixHandler::getHostName() const ::gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; - if (::strlen(hostname) == 0 || !isAcceptableHostname(hostname)) + if (::strlen(hostname) == 0 || !isAcceptableHostname(hostname)) { ::strcpy(hostname, "localhost.localdomain"); + } return hostname; } -unsigned int posixHandler::getProcessId() const -{ - return (::getpid()); +unsigned int posixHandler::getProcessId() const { + + return ::getpid(); } -unsigned int posixHandler::getThreadId() const -{ +unsigned int posixHandler::getThreadId() const { + #if VMIME_HAVE_GETTID return static_cast (::gettid()); #elif VMIME_HAVE_SYSCALL && VMIME_HAVE_SYSCALL_GETTID @@ -265,13 +267,14 @@ unsigned int posixHandler::getThreadId() const #else #error We have no implementation of getThreadId() for this platform! #endif + } #if VMIME_HAVE_MESSAGING_FEATURES -shared_ptr posixHandler::getSocketFactory() -{ +shared_ptr posixHandler::getSocketFactory() { + return m_socketFactory; } @@ -280,39 +283,40 @@ shared_ptr posixHandler::getSocketFactory() #if VMIME_HAVE_FILESYSTEM_FEATURES -shared_ptr posixHandler::getFileSystemFactory() -{ +shared_ptr posixHandler::getFileSystemFactory() { + return m_fileSysFactory; } -shared_ptr posixHandler::getChildProcessFactory() -{ +shared_ptr posixHandler::getChildProcessFactory() { + return m_childProcFactory; } #endif -void posixHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) -{ +void posixHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) { + int fd = open("/dev/urandom", O_RDONLY); - if (fd != -1) - { + if (fd != -1) { + read(fd, buffer, count); close(fd); - } - else // fallback - { - for (unsigned int i = 0 ; i < count ; ++i) + + } else { // fallback + + for (unsigned int i = 0 ; i < count ; ++i) { buffer[i] = static_cast (rand() % 255); + } } } -shared_ptr posixHandler::createCriticalSection() -{ +shared_ptr posixHandler::createCriticalSection() { + return make_shared (); } diff --git a/src/vmime/platforms/posix/posixHandler.hpp b/src/vmime/platforms/posix/posixHandler.hpp index d9eb4fbd..30417f17 100644 --- a/src/vmime/platforms/posix/posixHandler.hpp +++ b/src/vmime/platforms/posix/posixHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -48,8 +48,8 @@ namespace platforms { namespace posix { -class VMIME_EXPORT posixHandler : public vmime::platform::handler -{ +class VMIME_EXPORT posixHandler : public vmime::platform::handler { + public: posixHandler(); diff --git a/src/vmime/platforms/posix/posixSocket.cpp b/src/vmime/platforms/posix/posixSocket.cpp index e2bdd4b8..aec6a83e 100644 --- a/src/vmime/platforms/posix/posixSocket.cpp +++ b/src/vmime/platforms/posix/posixSocket.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -62,18 +62,17 @@ // Workaround for detection of strerror_r variants #if VMIME_HAVE_STRERROR_R -namespace -{ +namespace { + +char* vmime_strerror_r_result(int /* res */, char* buf) { -char* vmime_strerror_r_result(int /* res */, char* buf) -{ // XSI-compliant prototype: // int strerror_r(int errnum, char *buf, size_t buflen); return buf; } -char* vmime_strerror_r_result(char* res, char* /* buf */) -{ +char* vmime_strerror_r_result(char* res, char* /* buf */) { + // GNU-specific prototype: // char *strerror_r(int errnum, char *buf, size_t buflen); return res; @@ -95,29 +94,31 @@ namespace posix { // posixSocket::posixSocket(shared_ptr th) - : m_timeoutHandler(th), m_desc(-1), m_status(0) -{ + : m_timeoutHandler(th), + m_desc(-1), + m_status(0) { + } -posixSocket::~posixSocket() -{ - if (m_desc != -1) +posixSocket::~posixSocket() { + + if (m_desc != -1) { ::close(m_desc); + } } -void posixSocket::connect(const vmime::string& address, const vmime::port_t port) -{ +void posixSocket::connect(const vmime::string& address, const vmime::port_t port) { + // Close current connection, if any - if (m_desc != -1) - { + if (m_desc != -1) { ::close(m_desc); m_desc = -1; } - if (m_tracer) - { + if (m_tracer) { + std::ostringstream trace; trace << "Connecting to " << address << ", port " << port; @@ -136,20 +137,21 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port int sock = -1; int connectErrno = 0; - if (m_timeoutHandler != NULL) + if (m_timeoutHandler != NULL) { m_timeoutHandler->resetTimeOut(); + } for (struct ::addrinfo* curAddrInfo = addrInfo ; sock == -1 && curAddrInfo != NULL ; - curAddrInfo = curAddrInfo->ai_next, connectErrno = ETIMEDOUT) - { - if (curAddrInfo->ai_family != AF_INET && curAddrInfo->ai_family != AF_INET6) + curAddrInfo = curAddrInfo->ai_next, connectErrno = ETIMEDOUT) { + + if (curAddrInfo->ai_family != AF_INET && curAddrInfo->ai_family != AF_INET6) { continue; + } sock = ::socket(curAddrInfo->ai_family, curAddrInfo->ai_socktype, curAddrInfo->ai_protocol); - if (sock < 0) - { + if (sock < 0) { connectErrno = errno; continue; // try next } @@ -175,33 +177,33 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port #endif // VMIME_HAVE_SO_NOSIGPIPE - if (m_timeoutHandler != NULL) - { + if (m_timeoutHandler) { + ::fcntl(sock, F_SETFL, ::fcntl(sock, F_GETFL) | O_NONBLOCK); - if (::connect(sock, curAddrInfo->ai_addr, curAddrInfo->ai_addrlen) < 0) - { - switch (errno) - { - case 0: - case EINPROGRESS: - case EINTR: + if (::connect(sock, curAddrInfo->ai_addr, curAddrInfo->ai_addrlen) < 0) { + + switch (errno) { + + case 0: + case EINPROGRESS: + case EINTR: #if defined(EAGAIN) - case EAGAIN: + case EAGAIN: #endif // EAGAIN #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: + case EWOULDBLOCK: #endif // EWOULDBLOCK - // Connection in progress - break; + // Connection in progress + break; - default: + default: - connectErrno = errno; - ::close(sock); - sock = -1; - continue; // try next + connectErrno = errno; + ::close(sock); + sock = -1; + continue; // try next } // Wait for socket to be connected. @@ -213,8 +215,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port timeval startTime = { 0, 0 }; gettimeofday(&startTime, /* timezone */ NULL); - do - { + do { + pollfd fds[1]; fds[0].fd = sock; fds[0].events = POLLIN | POLLOUT; @@ -222,33 +224,34 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port const int ret = ::poll(fds, sizeof(fds) / sizeof(fds[0]), pollTimeout); // Success - if (ret > 0) - { - if (fds[0].revents & (POLLIN | POLLOUT)) - { + if (ret > 0) { + + if (fds[0].revents & (POLLIN | POLLOUT)) { + int error = 0; socklen_t len = sizeof(error); - if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) - { + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { + connectErrno = errno; - } - else - { - if (error != 0) + + } else { + + if (error != 0) { connectErrno = error; - else + } else { connected = true; + } } } break; - } + // Error - else if (ret < -1) - { - if (errno != EAGAIN && errno != EINTR) - { + } else if (ret < -1) { + + if (errno != EAGAIN && errno != EINTR) { + // Cancel connection connectErrno = errno; break; @@ -256,22 +259,22 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port } // Check for timeout - if (m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + if (m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Cancel connection connectErrno = ETIMEDOUT; break; - } - else - { + + } else { + // Reset timeout and keep waiting for connection m_timeoutHandler->resetTimeOut(); } - } - else - { + + } else { + // Keep waiting for connection } @@ -279,33 +282,33 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port gettimeofday(&curTime, /* timezone */ NULL); if (curAddrInfo->ai_next != NULL && - curTime.tv_usec - startTime.tv_usec >= tryNextTimeout * 1000) - { + curTime.tv_usec - startTime.tv_usec >= tryNextTimeout * 1000) { + connectErrno = ETIMEDOUT; break; } } while (true); - if (!connected) - { + if (!connected) { + ::close(sock); sock = -1; continue; // try next } break; - } - else - { + + } else { + // Connection successful break; } - } - else - { - if (::connect(sock, curAddrInfo->ai_addr, curAddrInfo->ai_addrlen) < 0) - { + + } else { + + if (::connect(sock, curAddrInfo->ai_addr, curAddrInfo->ai_addrlen) < 0) { + connectErrno = errno; ::close(sock); sock = -1; @@ -316,16 +319,12 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port ::freeaddrinfo(addrInfo); - if (sock == -1) - { - try - { + if (sock == -1) { + + try { throwSocketError(connectErrno); - } - catch (exceptions::socket_exception& e) - { - throw vmime::exceptions::connection_error - ("Error while connecting socket.", e); + } catch (exceptions::socket_exception& e) { // wrap + throw vmime::exceptions::connection_error("Error while connecting socket.", e); } } @@ -342,12 +341,11 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port addr.sin_port = htons(static_cast (port)); addr.sin_addr.s_addr = ::inet_addr(address.c_str()); - if (addr.sin_addr.s_addr == static_cast (-1)) - { + if (addr.sin_addr.s_addr == static_cast (-1)) { + ::hostent* hostInfo = ::gethostbyname(address.c_str()); - if (hostInfo == NULL) - { + if (hostInfo == NULL) { // Error: cannot resolve address throw vmime::exceptions::connection_error("Cannot resolve address."); } @@ -360,34 +358,29 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port // Get a new socket m_desc = ::socket(AF_INET, SOCK_STREAM, 0); - if (m_desc == -1) - { - try - { + if (m_desc == -1) { + + try { throwSocketError(errno); - } - catch (exceptions::socket_exception& e) - { - throw vmime::exceptions::connection_error - ("Error while creating socket.", e); + } catch (exceptions::socket_exception& e) { // wrap + throw vmime::exceptions::connection_error("Error while creating socket.", e); } } // Start connection - if (::connect(m_desc, reinterpret_cast (&addr), sizeof(addr)) == -1) - { - try - { + if (::connect(m_desc, reinterpret_cast (&addr), sizeof(addr)) == -1) { + + try { + throwSocketError(errno); - } - catch (exceptions::socket_exception& e) - { + + } catch (exceptions::socket_exception& e) { // wrap + ::close(m_desc); m_desc = -1; // Error - throw vmime::exceptions::connection_error - ("Error while connecting socket.", e); + throw vmime::exceptions::connection_error("Error while connecting socket.", e); } } @@ -397,8 +390,12 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port } -void posixSocket::resolve(struct ::addrinfo** addrInfo, const vmime::string& address, const vmime::port_t port) -{ +void posixSocket::resolve( + struct ::addrinfo** addrInfo, + const vmime::string& address, + const vmime::port_t port +) { + char portStr[16]; snprintf(portStr, sizeof(portStr), "%u", static_cast (port)); @@ -425,73 +422,73 @@ void posixSocket::resolve(struct ::addrinfo** addrInfo, const vmime::string& add struct ::gaicb* gaiRequests = &gaiRequest; int gaiError; - if ((gaiError = getaddrinfo_a(GAI_NOWAIT, &gaiRequests, 1, NULL)) != 0) - { - throw vmime::exceptions::connection_error - ("getaddrinfo_a() failed: " + std::string(gai_strerror(gaiError))); + if ((gaiError = getaddrinfo_a(GAI_NOWAIT, &gaiRequests, 1, NULL)) != 0) { + + throw vmime::exceptions::connection_error( + "getaddrinfo_a() failed: " + std::string(gai_strerror(gaiError)) + ); } - if (m_timeoutHandler != NULL) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } + + while (true) { - while (true) - { struct timespec gaiTimeout; gaiTimeout.tv_sec = 1; // query timeout handler every second gaiTimeout.tv_nsec = 0; gaiError = gai_suspend(&gaiRequests, 1, &gaiTimeout); - if (gaiError == 0 || gaiError == EAI_ALLDONE) - { + if (gaiError == 0 || gaiError == EAI_ALLDONE) { + const int ret = gai_error(&gaiRequest); - if (ret != 0) - { - throw vmime::exceptions::connection_error - ("getaddrinfo_a() request failed: " + std::string(gai_strerror(ret))); - } - else - { + if (ret != 0) { + + throw vmime::exceptions::connection_error( + "getaddrinfo_a() request failed: " + std::string(gai_strerror(ret)) + ); + + } else { + *addrInfo = gaiRequest.ar_result; break; } - } - else if (gaiError != EAI_AGAIN) - { - if (gaiError == EAI_SYSTEM) - { + + } else if (gaiError != EAI_AGAIN) { + + if (gaiError == EAI_SYSTEM) { + const int ret = gai_error(&gaiRequest); - if (ret != EAI_INPROGRESS && errno != 0) - { - try - { + if (ret != EAI_INPROGRESS && errno != 0) { + + try { throwSocketError(errno); - } - catch (exceptions::socket_exception& e) - { - throw vmime::exceptions::connection_error - ("Error while connecting socket.", e); + } catch (exceptions::socket_exception& e) { // wrap + throw vmime::exceptions::connection_error("Error while connecting socket.", e); } } - } - else - { - throw vmime::exceptions::connection_error - ("gai_suspend() failed: " + std::string(gai_strerror(gaiError))); + + } else { + + throw vmime::exceptions::connection_error( + "gai_suspend() failed: " + std::string(gai_strerror(gaiError)) + ); } } // Check for timeout - if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + if (m_timeoutHandler && m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + throw exceptions::operation_timed_out(); - } - else - { + + } else { + // Reset timeout and keep waiting for connection m_timeoutHandler->resetTimeOut(); } @@ -500,8 +497,8 @@ void posixSocket::resolve(struct ::addrinfo** addrInfo, const vmime::string& add #else // !VMIME_HAVE_GETADDRINFO_A - if (::getaddrinfo(address.c_str(), portStr, &hints, addrInfo) != 0) - { + if (::getaddrinfo(address.c_str(), portStr, &hints, addrInfo) != 0) { + // Error: cannot resolve address throw vmime::exceptions::connection_error("Cannot resolve address."); } @@ -511,10 +508,11 @@ void posixSocket::resolve(struct ::addrinfo** addrInfo, const vmime::string& add } -bool posixSocket::isConnected() const -{ - if (m_desc == -1) +bool posixSocket::isConnected() const { + + if (m_desc == -1) { return false; + } char buff; @@ -522,12 +520,13 @@ bool posixSocket::isConnected() const } -void posixSocket::disconnect() -{ - if (m_desc != -1) - { - if (m_tracer) +void posixSocket::disconnect() { + + if (m_desc != -1) { + + if (m_tracer) { m_tracer->traceSend("Disconnecting"); + } ::shutdown(m_desc, SHUT_RDWR); ::close(m_desc); @@ -537,8 +536,7 @@ void posixSocket::disconnect() } -static bool isNumericAddress(const char* address) -{ +static bool isNumericAddress(const char* address) { #if VMIME_HAVE_GETADDRINFO @@ -548,13 +546,13 @@ static bool isNumericAddress(const char* address) hint.ai_family = AF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(address, 0, &hint, &info) == 0) - { + if (getaddrinfo(address, 0, &hint, &info) == 0) { + freeaddrinfo(info); return true; - } - else - { + + } else { + return false; } @@ -567,22 +565,20 @@ static bool isNumericAddress(const char* address) } -const string posixSocket::getPeerAddress() const -{ +const string posixSocket::getPeerAddress() const { + // Get address of connected peer sockaddr peer; socklen_t peerLen = sizeof(peer); - if (getpeername(m_desc, &peer, &peerLen) != 0) - { + if (getpeername(m_desc, &peer, &peerLen) != 0) { throwSocketError(errno); } // Convert to numerical presentation format char buf[INET6_ADDRSTRLEN]; - if (!inet_ntop(peer.sa_family, &(reinterpret_cast (&peer))->sin_addr, buf, sizeof(buf))) - { + if (!inet_ntop(peer.sa_family, &(reinterpret_cast (&peer))->sin_addr, buf, sizeof(buf))) { throwSocketError(errno); } @@ -590,21 +586,19 @@ const string posixSocket::getPeerAddress() const } -const string posixSocket::getPeerName() const -{ +const string posixSocket::getPeerName() const { + // Get address of connected peer sockaddr peer; socklen_t peerLen = sizeof(peer); - if (getpeername(m_desc, &peer, &peerLen) != 0) - { + if (getpeername(m_desc, &peer, &peerLen) != 0) { throwSocketError(errno); } // If server address as specified when connecting is a numeric // address, try to get a host name for it - if (isNumericAddress(m_serverAddress.c_str())) - { + if (isNumericAddress(m_serverAddress.c_str())) { #if VMIME_HAVE_GETNAMEINFO @@ -613,8 +607,8 @@ const string posixSocket::getPeerName() const if (getnameinfo(reinterpret_cast (&peer), peerLen, host, sizeof(host), service, sizeof(service), - /* flags */ NI_NAMEREQD) == 0) - { + /* flags */ NI_NAMEREQD) == 0) { + return string(host); } @@ -623,8 +617,8 @@ const string posixSocket::getPeerName() const struct hostent *hp; if ((hp = gethostbyaddr(reinterpret_cast (&peer), - sizeof(peer), peer.sa_family)) != NULL) - { + sizeof(peer), peer.sa_family)) != NULL) { + return string(hp->h_name); } @@ -636,52 +630,56 @@ const string posixSocket::getPeerName() const } -size_t posixSocket::getBlockSize() const -{ +size_t posixSocket::getBlockSize() const { + return 16384; // 16 KB } -bool posixSocket::waitForData(const bool read, const bool write, const int msecs) -{ - for (int i = 0 ; i <= msecs / 10 ; ++i) - { +bool posixSocket::waitForData(const bool read, const bool write, const int msecs) { + + for (int i = 0 ; i <= msecs / 10 ; ++i) { + // Check whether data is available pollfd fds[1]; fds[0].fd = m_desc; fds[0].events = 0; - if (read) + if (read) { fds[0].events |= POLLIN; + } - if (write) + if (write) { fds[0].events |= POLLOUT; + } const int ret = ::poll(fds, sizeof(fds) / sizeof(fds[0]), 10 /* ms */); - if (ret < 0) - { - if (errno != EAGAIN && errno != EINTR) + if (ret < 0) { + + if (errno != EAGAIN && errno != EINTR) { throwSocketError(errno); - } - else if (ret > 0) - { - if (fds[0].revents & (POLLIN | POLLOUT)) + } + + } else if (ret > 0) { + + if (fds[0].revents & (POLLIN | POLLOUT)) { return true; + } } // No data available at this time // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Server did not react within timeout delay throw exceptions::operation_timed_out(); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -692,32 +690,32 @@ bool posixSocket::waitForData(const bool read, const bool write, const int msecs } -bool posixSocket::waitForRead(const int msecs) -{ +bool posixSocket::waitForRead(const int msecs) { + return waitForData(/* read */ true, /* write */ false, msecs); } -bool posixSocket::waitForWrite(const int msecs) -{ +bool posixSocket::waitForWrite(const int msecs) { + return waitForData(/* read */ false, /* write */ true, msecs); } -void posixSocket::receive(vmime::string& buffer) -{ +void posixSocket::receive(vmime::string& buffer) { + const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size); } -size_t posixSocket::receiveRaw(byte_t* buffer, const size_t count) -{ +size_t posixSocket::receiveRaw(byte_t* buffer, const size_t count) { + m_status &= ~STATUS_WOULDBLOCK; // Check whether data is available - if (!waitForRead(50 /* msecs */)) - { + if (!waitForRead(50 /* msecs */)) { + m_status |= STATUS_WOULDBLOCK; // Continue waiting for data @@ -727,22 +725,23 @@ size_t posixSocket::receiveRaw(byte_t* buffer, const size_t count) // Read available data ssize_t ret = ::recv(m_desc, buffer, count, 0); - if (ret < 0) - { - if (!IS_EAGAIN(errno)) + if (ret < 0) { + + if (!IS_EAGAIN(errno)) { throwSocketError(errno); + } // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Server did not react within timeout delay throwSocketError(errno); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -752,43 +751,43 @@ size_t posixSocket::receiveRaw(byte_t* buffer, const size_t count) // No data available at this time return 0; - } - else if (ret == 0) - { + + } else if (ret == 0) { + // Host shutdown throwSocketError(ENOTCONN); - } - else - { + + } else { + // Data received, reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } } return ret; } -void posixSocket::send(const vmime::string& buffer) -{ +void posixSocket::send(const vmime::string& buffer) { + sendRaw(reinterpret_cast (buffer.data()), buffer.length()); } -void posixSocket::send(const char* str) -{ +void posixSocket::send(const char* str) { + sendRaw(reinterpret_cast (str), ::strlen(str)); } -void posixSocket::sendRaw(const byte_t* buffer, const size_t count) -{ +void posixSocket::sendRaw(const byte_t* buffer, const size_t count) { + m_status &= ~STATUS_WOULDBLOCK; size_t size = count; - while (size > 0) - { + while (size > 0) { #if VMIME_HAVE_MSG_NOSIGNAL const ssize_t ret = ::send(m_desc, buffer, size, MSG_NOSIGNAL); @@ -796,28 +795,30 @@ void posixSocket::sendRaw(const byte_t* buffer, const size_t count) const ssize_t ret = ::send(m_desc, buffer, size, 0); #endif - if (ret <= 0) - { - if (ret < 0 && !IS_EAGAIN(errno)) + if (ret <= 0) { + + if (ret < 0 && !IS_EAGAIN(errno)) { throwSocketError(errno); + } waitForWrite(50 /* msecs */); - } - else - { + + } else { + buffer += ret; size -= ret; } } // Reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } } -size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) -{ +size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) { + m_status &= ~STATUS_WOULDBLOCK; #if VMIME_HAVE_MSG_NOSIGNAL @@ -826,22 +827,23 @@ size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) const ssize_t ret = ::send(m_desc, buffer, count, 0); #endif - if (ret <= 0) - { - if (ret < 0 && !IS_EAGAIN(errno)) + if (ret <= 0) { + + if (ret < 0 && !IS_EAGAIN(errno)) { throwSocketError(errno); + } // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Could not send data within timeout delay throw exceptions::operation_timed_out(); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -854,51 +856,57 @@ size_t posixSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) } // Reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } return ret; } -void posixSocket::throwSocketError(const int err) -{ +void posixSocket::throwSocketError(const int err) { + const char* msg = NULL; - switch (err) - { - case EACCES: msg = "EACCES: permission denied"; break; - case EAFNOSUPPORT: msg = "EAFNOSUPPORT: address family not supported"; break; - case EMFILE: msg = "EMFILE: process file table overflow"; break; - case ENFILE: msg = "ENFILE: system limit reached"; break; - case EPROTONOSUPPORT: msg = "EPROTONOSUPPORT: protocol not supported"; break; - case EAGAIN: msg = "EGAIN: blocking operation"; break; - case EBADF: msg = "EBADF: invalid descriptor"; break; - case ECONNRESET: msg = "ECONNRESET: connection reset by peer"; break; - case EFAULT: msg = "EFAULT: bad user space address"; break; - case EINTR: msg = "EINTR: signal occurred before transmission"; break; - case EINVAL: msg = "EINVAL: invalid argument"; break; - case EMSGSIZE: msg = "EMSGSIZE: message cannot be sent atomically"; break; - case ENOBUFS: msg = "ENOBUFS: output queue is full"; break; - case ENOMEM: msg = "ENOMEM: out of memory"; break; - case EPIPE: msg = "EPIPE: broken pipe"; break; - case ENOTCONN: msg = "ENOTCONN: not connected"; break; - case ECONNREFUSED: msg = "ECONNREFUSED: connection refused"; break; + switch (err) { + + case EACCES: msg = "EACCES: permission denied"; break; + case EAFNOSUPPORT: msg = "EAFNOSUPPORT: address family not supported"; break; + case EMFILE: msg = "EMFILE: process file table overflow"; break; + case ENFILE: msg = "ENFILE: system limit reached"; break; + case EPROTONOSUPPORT: msg = "EPROTONOSUPPORT: protocol not supported"; break; + case EAGAIN: msg = "EGAIN: blocking operation"; break; + case EBADF: msg = "EBADF: invalid descriptor"; break; + case ECONNRESET: msg = "ECONNRESET: connection reset by peer"; break; + case EFAULT: msg = "EFAULT: bad user space address"; break; + case EINTR: msg = "EINTR: signal occurred before transmission"; break; + case EINVAL: msg = "EINVAL: invalid argument"; break; + case EMSGSIZE: msg = "EMSGSIZE: message cannot be sent atomically"; break; + case ENOBUFS: msg = "ENOBUFS: output queue is full"; break; + case ENOMEM: msg = "ENOMEM: out of memory"; break; + case EPIPE: msg = "EPIPE: broken pipe"; break; + case ENOTCONN: msg = "ENOTCONN: not connected"; break; + case ECONNREFUSED: msg = "ECONNREFUSED: connection refused"; break; } - if (msg) - { + if (msg) { + throw exceptions::socket_exception(msg); - } - else - { + + } else { // Use strerror() to get string describing error number #if VMIME_HAVE_STRERROR_R char errbuf[512]; - throw exceptions::socket_exception(vmime_strerror_r_result(strerror_r(err, errbuf, sizeof(errbuf)), errbuf)); + + throw exceptions::socket_exception( + vmime_strerror_r_result( + strerror_r(err, errbuf, sizeof(errbuf)), + errbuf + ) + ); #else // !VMIME_HAVE_STRERROR_R @@ -911,26 +919,26 @@ void posixSocket::throwSocketError(const int err) } -unsigned int posixSocket::getStatus() const -{ +unsigned int posixSocket::getStatus() const { + return m_status; } -shared_ptr posixSocket::getTimeoutHandler() -{ +shared_ptr posixSocket::getTimeoutHandler() { + return m_timeoutHandler; } -void posixSocket::setTracer(const shared_ptr & tracer) -{ +void posixSocket::setTracer(const shared_ptr & tracer) { + m_tracer = tracer; } -shared_ptr posixSocket::getTracer() -{ +shared_ptr posixSocket::getTracer() { + return m_tracer; } @@ -940,15 +948,15 @@ shared_ptr posixSocket::getTracer() // posixSocketFactory // -shared_ptr posixSocketFactory::create() -{ +shared_ptr posixSocketFactory::create() { + shared_ptr th; return make_shared (th); } -shared_ptr posixSocketFactory::create(const shared_ptr & th) -{ +shared_ptr posixSocketFactory::create(const shared_ptr & th) { + return make_shared (th); } diff --git a/src/vmime/platforms/posix/posixSocket.hpp b/src/vmime/platforms/posix/posixSocket.hpp index f253c17b..7d732b74 100644 --- a/src/vmime/platforms/posix/posixSocket.hpp +++ b/src/vmime/platforms/posix/posixSocket.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace platforms { namespace posix { -class posixSocket : public vmime::net::socket -{ +class posixSocket : public vmime::net::socket { + public: posixSocket(shared_ptr th); @@ -99,8 +99,8 @@ private: -class posixSocketFactory : public vmime::net::socketFactory -{ +class posixSocketFactory : public vmime::net::socketFactory { + public: shared_ptr create(); diff --git a/src/vmime/platforms/windows/windowsCodepages.hpp b/src/vmime/platforms/windows/windowsCodepages.hpp index e66b2303..1457c59a 100644 --- a/src/vmime/platforms/windows/windowsCodepages.hpp +++ b/src/vmime/platforms/windows/windowsCodepages.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,12 +39,10 @@ namespace platforms { namespace windows { -class windowsCodepages -{ -public: +struct windowsCodepages { + + static int getByName(const char* s8_Name) { - static int getByName(const char* s8_Name) - { if (stricmp(s8_Name, "ASMO-708") == 0) return 708; if (stricmp(s8_Name, "big5") == 0) return 950; if (stricmp(s8_Name, "cp1025") == 0) return 21025; diff --git a/src/vmime/platforms/windows/windowsCriticalSection.cpp b/src/vmime/platforms/windows/windowsCriticalSection.cpp index d6ef0c45..c0a0bec4 100644 --- a/src/vmime/platforms/windows/windowsCriticalSection.cpp +++ b/src/vmime/platforms/windows/windowsCriticalSection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,26 +35,26 @@ namespace platforms { namespace windows { -windowsCriticalSection::windowsCriticalSection() -{ +windowsCriticalSection::windowsCriticalSection() { + InitializeCriticalSectionAndSpinCount(&m_cs, 0x400); } -windowsCriticalSection::~windowsCriticalSection() -{ +windowsCriticalSection::~windowsCriticalSection() { + DeleteCriticalSection(&m_cs); } -void windowsCriticalSection::lock() -{ +void windowsCriticalSection::lock() { + EnterCriticalSection(&m_cs); } -void windowsCriticalSection::unlock() -{ +void windowsCriticalSection::unlock() { + LeaveCriticalSection(&m_cs); } diff --git a/src/vmime/platforms/windows/windowsCriticalSection.hpp b/src/vmime/platforms/windows/windowsCriticalSection.hpp index 7ed07835..ffe82942 100644 --- a/src/vmime/platforms/windows/windowsCriticalSection.hpp +++ b/src/vmime/platforms/windows/windowsCriticalSection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace platforms { namespace windows { -class windowsCriticalSection : public utility::sync::criticalSection -{ +class windowsCriticalSection : public utility::sync::criticalSection { + public: windowsCriticalSection(); diff --git a/src/vmime/platforms/windows/windowsFile.cpp b/src/vmime/platforms/windows/windowsFile.cpp index b743641b..774731c7 100644 --- a/src/vmime/platforms/windows/windowsFile.cpp +++ b/src/vmime/platforms/windows/windowsFile.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,152 +41,179 @@ namespace platforms { namespace windows { -shared_ptr windowsFileSystemFactory::create(const vmime::utility::file::path& path) const -{ +shared_ptr windowsFileSystemFactory::create( + const vmime::utility::file::path& path +) const { + return make_shared (path); } -const vmime::utility::file::path windowsFileSystemFactory::stringToPath(const vmime::string& str) const -{ - return (stringToPathImpl(str)); +const vmime::utility::file::path windowsFileSystemFactory::stringToPath( + const vmime::string& str +) const { + + return stringToPathImpl(str); } -const vmime::string windowsFileSystemFactory::pathToString(const vmime::utility::file::path& path) const -{ - return (pathToStringImpl(path)); +const vmime::string windowsFileSystemFactory::pathToString( + const vmime::utility::file::path& path +) const { + + return pathToStringImpl(path); } -const vmime::utility::file::path windowsFileSystemFactory::stringToPathImpl(const vmime::string& str) -{ +const vmime::utility::file::path windowsFileSystemFactory::stringToPathImpl( + const vmime::string& str +) { + vmime::size_t offset = 0; vmime::size_t prev = 0; vmime::utility::file::path path; - while ((offset = str.find_first_of("\\", offset)) != vmime::string::npos) - { - if (offset != prev) - { - path.appendComponent - (vmime::utility::file::path::component - (vmime::string(str.begin() + prev, str.begin() + offset))); + while ((offset = str.find_first_of("\\", offset)) != vmime::string::npos) { + + if (offset != prev) { + + path.appendComponent( + vmime::utility::file::path::component( + vmime::string(str.begin() + prev, str.begin() + offset) + ) + ); } prev = offset + 1; offset++; } - if (prev < str.length()) - { - path.appendComponent - (vmime::utility::file::path::component - (vmime::string(str.begin() + prev, str.end()))); + if (prev < str.length()) { + + path.appendComponent( + vmime::utility::file::path::component( + vmime::string(str.begin() + prev, str.end()) + ) + ); } - return (path); + return path; } -const vmime::string windowsFileSystemFactory::pathToStringImpl(const vmime::utility::file::path& path) -{ +const vmime::string windowsFileSystemFactory::pathToStringImpl( + const vmime::utility::file::path& path +) { + vmime::string native = ""; - for (int i = 0 ; i < path.getSize() ; ++i) - { - if (i > 0) + for (int i = 0 ; i < path.getSize() ; ++i) { + + if (i > 0) { native += "\\"; + } native += path[i].getBuffer(); } - return (native); + return native; } -bool windowsFileSystemFactory::isValidPathComponent(const vmime::utility::file::path::component& comp) const -{ + +bool windowsFileSystemFactory::isValidPathComponent( + const vmime::utility::file::path::component& comp +) const { + return isValidPathComponent(comp, false); } + bool windowsFileSystemFactory::isValidPathComponent( const vmime::utility::file::path::component& comp, - bool firstComponent) const -{ + bool firstComponent +) const { + const string& buffer = comp.getBuffer(); // If first component, check if component is a drive - if (firstComponent && (buffer.length() == 2) && (buffer[1] == ':')) - { + if (firstComponent && (buffer.length() == 2) && (buffer[1] == ':')) { + char drive = tolower(buffer[0]); - if ((drive >= 'a') && (drive <= 'z')) + + if ((drive >= 'a') && (drive <= 'z')) { return true; + } } // Check for invalid characters - for (size_t i = 0 ; i < buffer.length() ; ++i) - { + for (size_t i = 0 ; i < buffer.length() ; ++i) { + const unsigned char c = buffer[i]; - switch (c) - { - // Reserved characters - case '<': case '>': case ':': - case '"': case '/': case '\\': - case '|': case '$': case '*': + switch (c) { - return false; + // Reserved characters + case '<': case '>': case ':': + case '"': case '/': case '\\': + case '|': case '$': case '*': - default: - - if (c <= 31) return false; + + default: + + if (c <= 31) { + return false; + } } } string upperBuffer = vmime::utility::stringUtils::toUpper(buffer); // Check for reserved names - if (upperBuffer.length() == 3) - { - if (upperBuffer == "CON" || buffer == "PRN" || buffer == "AUX" || buffer == "NUL") + if (upperBuffer.length() == 3) { + + if (upperBuffer == "CON" || buffer == "PRN" || buffer == "AUX" || buffer == "NUL") { return false; - } - else if (upperBuffer.length() == 4) - { + } + + } else if (upperBuffer.length() == 4) { + if ((upperBuffer.substr(0, 3) == "COM") && // COM0 to COM9 - (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) - { + (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) { + + return false; + + } else if ((upperBuffer.substr(0, 3) == "LPT") && // LPT0 to LPT9 + (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) { + return false; } - else if ((upperBuffer.substr(0, 3) == "LPT") && // LPT0 to LPT9 - (upperBuffer[3] >= '0') && (upperBuffer[3] <= '9')) - { - return false; - } - } - return true; -} - - -bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const -{ - for (int i = 0 ; i < path.getSize() ; ++i) - { - if (!isValidPathComponent(path[i], (i==0))) - return false; } return true; } -void windowsFileSystemFactory::reportError(const vmime::utility::path& path, const int err) -{ +bool windowsFileSystemFactory::isValidPath(const vmime::utility::file::path& path) const { + + for (int i = 0 ; i < path.getSize() ; ++i) { + + if (!isValidPathComponent(path[i], (i == 0))) { + return false; + } + } + + return true; +} + + +void windowsFileSystemFactory::reportError(const vmime::utility::path& path, const int err) { + vmime::string desc; LPVOID lpMsgBuf; + if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -196,22 +223,27 @@ void windowsFileSystemFactory::reportError(const vmime::utility::path& path, con MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, - NULL )) - { - desc = (char*)lpMsgBuf; - LocalFree( lpMsgBuf ); + NULL)) { + + desc = (char*) lpMsgBuf; + LocalFree(lpMsgBuf); } throw vmime::exceptions::filesystem_exception(desc, path); } + + + windowsFile::windowsFile(const vmime::utility::file::path& path) -: m_path(path), m_nativePath(windowsFileSystemFactory::pathToStringImpl(path)) -{ + : m_path(path), + m_nativePath(windowsFileSystemFactory::pathToStringImpl(path)) { + } -void windowsFile::createFile() -{ + +void windowsFile::createFile() { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_WRITE, @@ -219,36 +251,49 @@ void windowsFile::createFile() NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } CloseHandle(hFile); } -void windowsFile::createDirectory(const bool createAll) -{ + +void windowsFile::createDirectory(const bool createAll) { + createDirectoryImpl(m_path, m_path, createAll); } -bool windowsFile::isFile() const -{ + +bool windowsFile::isFile() const { + DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); - if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) + + if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) { return false; + } + return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == 0; } -bool windowsFile::isDirectory() const -{ + +bool windowsFile::isDirectory() const { + DWORD dwFileAttribute = GetFileAttributes(m_nativePath.c_str()); - if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) + + if (dwFileAttribute == INVALID_FILE_ATTRIBUTES) { return false; + } + return (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; } -bool windowsFile::canRead() const -{ + +bool windowsFile::canRead() const { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_READ, @@ -256,15 +301,21 @@ bool windowsFile::canRead() const NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { return false; + } + CloseHandle(hFile); + return true; } -bool windowsFile::canWrite() const -{ + +bool windowsFile::canWrite() const { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_WRITE, @@ -272,15 +323,21 @@ bool windowsFile::canWrite() const NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { return false; + } + CloseHandle(hFile); + return true; } -windowsFile::length_type windowsFile::getLength() -{ + +windowsFile::length_type windowsFile::getLength() { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_READ, @@ -288,158 +345,212 @@ windowsFile::length_type windowsFile::getLength() NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } DWORD dwSize = GetFileSize(hFile, NULL); + CloseHandle(hFile); return dwSize; } -const vmime::utility::path& windowsFile::getFullPath() const -{ + +const vmime::utility::path& windowsFile::getFullPath() const { + return m_path; } -bool windowsFile::exists() const -{ + +bool windowsFile::exists() const { + WIN32_FIND_DATA findData; HANDLE hFind = FindFirstFile(m_nativePath.c_str(), &findData); - if (hFind != INVALID_HANDLE_VALUE) - { + + if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); return true; } + return false; } -shared_ptr windowsFile::getParent() const -{ - if (m_path.isEmpty()) + +shared_ptr windowsFile::getParent() const { + + if (m_path.isEmpty()) { return null; - else + } else { return make_shared (m_path.getParent()); + } } -void windowsFile::rename(const path& newName) -{ + +void windowsFile::rename(const path& newName) { + const vmime::string newNativeName = windowsFileSystemFactory::pathToStringImpl(newName); - if (MoveFile(m_nativePath.c_str(), newNativeName.c_str())) - { + + if (MoveFile(m_nativePath.c_str(), newNativeName.c_str())) { + m_path = newName; m_nativePath = newNativeName; + + } else { + + windowsFileSystemFactory::reportError(m_path, GetLastError()); } - else - windowsFileSystemFactory::reportError(m_path, GetLastError()); } -void windowsFile::remove() -{ - if (!DeleteFile(m_nativePath.c_str())) + +void windowsFile::remove() { + + if (!DeleteFile(m_nativePath.c_str())) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } } -shared_ptr windowsFile::getFileWriter() -{ + +shared_ptr windowsFile::getFileWriter() { + return make_shared (m_path, m_nativePath); } -shared_ptr windowsFile::getFileReader() -{ + +shared_ptr windowsFile::getFileReader() { + return make_shared (m_path, m_nativePath); } -shared_ptr windowsFile::getFiles() const -{ + +shared_ptr windowsFile::getFiles() const { + return make_shared (m_path, m_nativePath); } -void windowsFile::createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive) -{ + +void windowsFile::createDirectoryImpl( + const vmime::utility::file::path& fullPath, + const vmime::utility::file::path& path, + const bool recursive +) { + const vmime::string nativePath = windowsFileSystemFactory::pathToStringImpl(path); windowsFile tmp(path); - if (tmp.isDirectory()) + + if (tmp.isDirectory()) { return; + } - if (!path.isEmpty() && recursive) + if (!path.isEmpty() && recursive) { createDirectoryImpl(fullPath, path.getParent(), true); + } - if (!CreateDirectory(nativePath.c_str(), NULL)) + if (!CreateDirectory(nativePath.c_str(), NULL)) { windowsFileSystemFactory::reportError(fullPath, GetLastError()); + } } -windowsFileIterator::windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath) -: m_path(path), m_nativePath(nativePath), m_moreElements(false), m_hFind(INVALID_HANDLE_VALUE) -{ + + +windowsFileIterator::windowsFileIterator( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath), + m_moreElements(false), + m_hFind(INVALID_HANDLE_VALUE) { + findFirst(); } -windowsFileIterator::~windowsFileIterator() -{ - if (m_hFind != INVALID_HANDLE_VALUE) + +windowsFileIterator::~windowsFileIterator() { + + if (m_hFind != INVALID_HANDLE_VALUE) { FindClose(m_hFind); + } } -bool windowsFileIterator::hasMoreElements() const -{ + +bool windowsFileIterator::hasMoreElements() const { + return m_moreElements; } -shared_ptr windowsFileIterator::nextElement() -{ - shared_ptr pFile = make_shared - (m_path / vmime::utility::file::path::component(m_findData.cFileName)); + +shared_ptr windowsFileIterator::nextElement() { + + shared_ptr pFile = make_shared ( + m_path / vmime::utility::file::path::component(m_findData.cFileName) + ); findNext(); return pFile; } -void windowsFileIterator::findFirst() -{ + +void windowsFileIterator::findFirst() { + m_hFind = FindFirstFile(m_nativePath.c_str(), &m_findData); - if (m_hFind == INVALID_HANDLE_VALUE) - { + + if (m_hFind == INVALID_HANDLE_VALUE) { m_moreElements = false; return; } m_moreElements = true; - if (isCurrentOrParentDir()) + + if (isCurrentOrParentDir()) { findNext(); + } } -void windowsFileIterator::findNext() -{ - do - { - if (!FindNextFile(m_hFind, &m_findData)) - { + +void windowsFileIterator::findNext() { + + do { + + if (!FindNextFile(m_hFind, &m_findData)) { m_moreElements = false; return; } - } - while (isCurrentOrParentDir()); + + } while (isCurrentOrParentDir()); } -bool windowsFileIterator::isCurrentOrParentDir() const -{ + +bool windowsFileIterator::isCurrentOrParentDir() const { + vmime::string s(m_findData.cFileName); - if ((s == ".") || (s == "..")) + + if ((s == ".") || (s == "..")) { return true; + } + return false; } -windowsFileReader::windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath) -: m_path(path), m_nativePath(nativePath) -{ + + +windowsFileReader::windowsFileReader( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath) { + } -shared_ptr windowsFileReader::getInputStream() -{ + +shared_ptr windowsFileReader::getInputStream() { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_READ, @@ -447,74 +558,101 @@ shared_ptr windowsFileReader::getInputStream() NULL, OPEN_EXISTING, 0, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } + return make_shared (m_path, hFile); } -windowsFileReaderInputStream::windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile) -: m_path(path), m_hFile(hFile) -{ + +windowsFileReaderInputStream::windowsFileReaderInputStream( + const vmime::utility::file::path& path, + HANDLE hFile +) + : m_path(path), + m_hFile(hFile) { + } -windowsFileReaderInputStream::~windowsFileReaderInputStream() -{ +windowsFileReaderInputStream::~windowsFileReaderInputStream() { + CloseHandle(m_hFile); } -bool windowsFileReaderInputStream::eof() const -{ + +bool windowsFileReaderInputStream::eof() const { + DWORD dwSize = GetFileSize(m_hFile, NULL); DWORD dwPosition = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); - return (dwSize == dwPosition); + + return dwSize == dwPosition; } -void windowsFileReaderInputStream::reset() -{ + +void windowsFileReaderInputStream::reset() { + SetFilePointer(m_hFile, 0, NULL, FILE_BEGIN); } -size_t windowsFileReaderInputStream::read(byte_t* const data, const size_t count) -{ + +size_t windowsFileReaderInputStream::read(byte_t* const data, const size_t count) { + DWORD dwBytesRead; - if (!ReadFile(m_hFile, (LPVOID)data, (DWORD)count, &dwBytesRead, NULL)) + + if (!ReadFile(m_hFile, (LPVOID) data, (DWORD) count, &dwBytesRead, NULL)) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } + return dwBytesRead; } -size_t windowsFileReaderInputStream::skip(const size_t count) -{ + +size_t windowsFileReaderInputStream::skip(const size_t count) { + DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); - DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)count, NULL, FILE_CURRENT); - return (dwNewPos - dwCurPos); + DWORD dwNewPos = SetFilePointer(m_hFile, (LONG) count, NULL, FILE_CURRENT); + + return dwNewPos - dwCurPos; } -size_t windowsFileReaderInputStream::getPosition() const -{ + +size_t windowsFileReaderInputStream::getPosition() const { + DWORD dwCurPos = SetFilePointer(m_hFile, 0, NULL, FILE_CURRENT); - if (dwCurPos == INVALID_SET_FILE_POINTER) + if (dwCurPos == INVALID_SET_FILE_POINTER) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } return static_cast (dwCurPos); } -void windowsFileReaderInputStream::seek(const size_t pos) -{ - DWORD dwNewPos = SetFilePointer(m_hFile, (LONG)pos, NULL, FILE_BEGIN); +void windowsFileReaderInputStream::seek(const size_t pos) { - if (dwNewPos == INVALID_SET_FILE_POINTER) + DWORD dwNewPos = SetFilePointer(m_hFile, (LONG) pos, NULL, FILE_BEGIN); + + if (dwNewPos == INVALID_SET_FILE_POINTER) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } } -windowsFileWriter::windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath) -: m_path(path), m_nativePath(nativePath) -{ + + +windowsFileWriter::windowsFileWriter( + const vmime::utility::file::path& path, + const vmime::string& nativePath +) + : m_path(path), + m_nativePath(nativePath) { + } -shared_ptr windowsFileWriter::getOutputStream() -{ +shared_ptr windowsFileWriter::getOutputStream() { + HANDLE hFile = CreateFile( m_nativePath.c_str(), GENERIC_WRITE, @@ -522,32 +660,45 @@ shared_ptr windowsFileWriter::getOutputStream() NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, - NULL); - if (hFile == INVALID_HANDLE_VALUE) + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } + return make_shared (m_path, hFile); } -windowsFileWriterOutputStream::windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile) -: m_path(path), m_hFile(hFile) -{ + +windowsFileWriterOutputStream::windowsFileWriterOutputStream( + const vmime::utility::file::path& path, + HANDLE hFile +) + : m_path(path), + m_hFile(hFile) { + } -windowsFileWriterOutputStream::~windowsFileWriterOutputStream() -{ + +windowsFileWriterOutputStream::~windowsFileWriterOutputStream() { + CloseHandle(m_hFile); } -void windowsFileWriterOutputStream::writeImpl(const byte_t* const data, const size_t count) -{ + +void windowsFileWriterOutputStream::writeImpl(const byte_t* const data, const size_t count) { + DWORD dwBytesWritten; - if (!WriteFile(m_hFile, data, (DWORD)count, &dwBytesWritten, NULL)) + + if (!WriteFile(m_hFile, data, (DWORD) count, &dwBytesWritten, NULL)) { windowsFileSystemFactory::reportError(m_path, GetLastError()); + } } -void windowsFileWriterOutputStream::flush() -{ +void windowsFileWriterOutputStream::flush() { + // TODO } diff --git a/src/vmime/platforms/windows/windowsFile.hpp b/src/vmime/platforms/windows/windowsFile.hpp index 3543ee8a..dc4b5ed9 100644 --- a/src/vmime/platforms/windows/windowsFile.hpp +++ b/src/vmime/platforms/windows/windowsFile.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace platforms { namespace windows { -class windowsFileSystemFactory : public vmime::utility::fileSystemFactory -{ +class windowsFileSystemFactory : public vmime::utility::fileSystemFactory { + public: shared_ptr create(const vmime::utility::file::path& path) const; @@ -63,8 +63,8 @@ public: }; -class windowsFile : public vmime::utility::file -{ +class windowsFile : public vmime::utility::file { + public: windowsFile(const vmime::utility::file::path& path); @@ -97,7 +97,11 @@ public: private: - static void createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive = false); + static void createDirectoryImpl( + const vmime::utility::file::path& fullPath, + const vmime::utility::file::path& path, + const bool recursive = false + ); private: @@ -106,8 +110,8 @@ private: }; -class windowsFileIterator : public vmime::utility::fileIterator -{ +class windowsFileIterator : public vmime::utility::fileIterator { + public: windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -132,8 +136,8 @@ private: }; -class windowsFileReader : public vmime::utility::fileReader -{ +class windowsFileReader : public vmime::utility::fileReader { + public: windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -149,8 +153,8 @@ private: }; -class windowsFileReaderInputStream : public vmime::utility::inputStream -{ +class windowsFileReaderInputStream : public vmime::utility::inputStream { + public: windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile); @@ -172,8 +176,8 @@ private: }; -class windowsFileWriter : public vmime::utility::fileWriter -{ +class windowsFileWriter : public vmime::utility::fileWriter { + public: windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath); @@ -189,8 +193,8 @@ private: }; -class windowsFileWriterOutputStream : public vmime::utility::outputStream -{ +class windowsFileWriterOutputStream : public vmime::utility::outputStream { + public: windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile); diff --git a/src/vmime/platforms/windows/windowsHandler.cpp b/src/vmime/platforms/windows/windowsHandler.cpp index 294a62d9..551f6726 100644 --- a/src/vmime/platforms/windows/windowsHandler.cpp +++ b/src/vmime/platforms/windows/windowsHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -51,8 +51,8 @@ namespace platforms { namespace windows { -windowsHandler::windowsHandler() -{ +windowsHandler::windowsHandler() { + WSAData wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); @@ -62,23 +62,24 @@ windowsHandler::windowsHandler() #if VMIME_HAVE_FILESYSTEM_FEATURES m_fileSysFactory = make_shared (); #endif + } -windowsHandler::~windowsHandler() -{ +windowsHandler::~windowsHandler() { + WSACleanup(); } -unsigned long windowsHandler::getUnixTime() const -{ +unsigned long windowsHandler::getUnixTime() const { + return static_cast (::time(NULL)); } -const vmime::datetime windowsHandler::getCurrentLocalTime() const -{ +const vmime::datetime windowsHandler::getCurrentLocalTime() const { + const time_t t(::time(NULL)); // Get the local time @@ -113,25 +114,30 @@ const vmime::datetime windowsHandler::getCurrentLocalTime() const const int diff = (const int)(::mktime(&local) - ::mktime(&gmt)); // Return the date - return vmime::datetime(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, - local.tm_hour, local.tm_min, local.tm_sec, diff / 60); // minutes needed + return vmime::datetime( + local.tm_year + 1900, local.tm_mon + 1, local.tm_mday, + local.tm_hour, local.tm_min, local.tm_sec, diff / 60 // minutes needed + ); } -const vmime::charset windowsHandler::getLocalCharset() const -{ +const vmime::charset windowsHandler::getLocalCharset() const { + #if VMIME_HAVE_MLANG + char szCharset[256]; CoInitialize(NULL); { IMultiLanguage* pMultiLanguage; + CoCreateInstance( CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, - (void**)&pMultiLanguage); + (void**) &pMultiLanguage + ); UINT codePage = GetACP(); MIMECPINFO cpInfo; @@ -139,98 +145,106 @@ const vmime::charset windowsHandler::getLocalCharset() const int nLengthW = lstrlenW(cpInfo.wszBodyCharset) + 1; - WideCharToMultiByte(codePage, 0, cpInfo.wszBodyCharset, nLengthW, szCharset, sizeof(szCharset), NULL, NULL ); + WideCharToMultiByte( + codePage, 0, cpInfo.wszBodyCharset, nLengthW, + szCharset, sizeof(szCharset), NULL, NULL + ); pMultiLanguage->Release(); - } CoUninitialize(); return vmime::charset(szCharset); + #else // VMIME_HAVE_MLANG + vmime::string ch = vmime::charsets::ISO8859_1; // default - switch (GetACP()) - { - case 437: ch = vmime::charsets::CP_437; break; - case 737: ch = vmime::charsets::CP_737; break; - case 775: ch = vmime::charsets::CP_775; break; - case 850: ch = vmime::charsets::CP_850; break; - case 852: ch = vmime::charsets::CP_852; break; - case 853: ch = vmime::charsets::CP_853; break; - case 855: ch = vmime::charsets::CP_855; break; - case 857: ch = vmime::charsets::CP_857; break; - case 858: ch = vmime::charsets::CP_858; break; - case 860: ch = vmime::charsets::CP_860; break; - case 861: ch = vmime::charsets::CP_861; break; - case 862: ch = vmime::charsets::CP_862; break; - case 863: ch = vmime::charsets::CP_863; break; - case 864: ch = vmime::charsets::CP_864; break; - case 865: ch = vmime::charsets::CP_865; break; - case 866: ch = vmime::charsets::CP_866; break; - case 869: ch = vmime::charsets::CP_869; break; - case 874: ch = vmime::charsets::CP_874; break; + switch (GetACP()) { - case 1125: ch = vmime::charsets::CP_1125; break; - case 1250: ch = vmime::charsets::CP_1250; break; - case 1251: ch = vmime::charsets::CP_1251; break; - case 1252: ch = vmime::charsets::CP_1252; break; - case 1253: ch = vmime::charsets::CP_1253; break; - case 1254: ch = vmime::charsets::CP_1254; break; - case 1255: ch = vmime::charsets::CP_1255; break; - case 1256: ch = vmime::charsets::CP_1256; break; - case 1257: ch = vmime::charsets::CP_1257; break; + case 437: ch = vmime::charsets::CP_437; break; + case 737: ch = vmime::charsets::CP_737; break; + case 775: ch = vmime::charsets::CP_775; break; + case 850: ch = vmime::charsets::CP_850; break; + case 852: ch = vmime::charsets::CP_852; break; + case 853: ch = vmime::charsets::CP_853; break; + case 855: ch = vmime::charsets::CP_855; break; + case 857: ch = vmime::charsets::CP_857; break; + case 858: ch = vmime::charsets::CP_858; break; + case 860: ch = vmime::charsets::CP_860; break; + case 861: ch = vmime::charsets::CP_861; break; + case 862: ch = vmime::charsets::CP_862; break; + case 863: ch = vmime::charsets::CP_863; break; + case 864: ch = vmime::charsets::CP_864; break; + case 865: ch = vmime::charsets::CP_865; break; + case 866: ch = vmime::charsets::CP_866; break; + case 869: ch = vmime::charsets::CP_869; break; + case 874: ch = vmime::charsets::CP_874; break; - case 28591: ch = vmime::charsets::ISO8859_1; break; - case 28592: ch = vmime::charsets::ISO8859_2; break; - case 28593: ch = vmime::charsets::ISO8859_3; break; - case 28594: ch = vmime::charsets::ISO8859_4; break; - case 28595: ch = vmime::charsets::ISO8859_5; break; - case 28596: ch = vmime::charsets::ISO8859_6; break; - case 28597: ch = vmime::charsets::ISO8859_7; break; - case 28598: ch = vmime::charsets::ISO8859_8; break; - case 28599: ch = vmime::charsets::ISO8859_9; break; - case 28605: ch = vmime::charsets::ISO8859_15; break; + case 1125: ch = vmime::charsets::CP_1125; break; + case 1250: ch = vmime::charsets::CP_1250; break; + case 1251: ch = vmime::charsets::CP_1251; break; + case 1252: ch = vmime::charsets::CP_1252; break; + case 1253: ch = vmime::charsets::CP_1253; break; + case 1254: ch = vmime::charsets::CP_1254; break; + case 1255: ch = vmime::charsets::CP_1255; break; + case 1256: ch = vmime::charsets::CP_1256; break; + case 1257: ch = vmime::charsets::CP_1257; break; - case 65000: ch = vmime::charsets::UTF_7; break; - case 65001: ch = vmime::charsets::UTF_8; break; + case 28591: ch = vmime::charsets::ISO8859_1; break; + case 28592: ch = vmime::charsets::ISO8859_2; break; + case 28593: ch = vmime::charsets::ISO8859_3; break; + case 28594: ch = vmime::charsets::ISO8859_4; break; + case 28595: ch = vmime::charsets::ISO8859_5; break; + case 28596: ch = vmime::charsets::ISO8859_6; break; + case 28597: ch = vmime::charsets::ISO8859_7; break; + case 28598: ch = vmime::charsets::ISO8859_8; break; + case 28599: ch = vmime::charsets::ISO8859_9; break; + case 28605: ch = vmime::charsets::ISO8859_15; break; + + case 65000: ch = vmime::charsets::UTF_7; break; + case 65001: ch = vmime::charsets::UTF_8; break; } - return (vmime::charset(ch)); + return vmime::charset(ch); + #endif + } -const vmime::string windowsHandler::getHostName() const -{ +const vmime::string windowsHandler::getHostName() const { + char hostname[1024]; DWORD hostnameLen; // First, try to get a Fully-Qualified Domain Name (FQDN) - for (int cnf = ComputerNameDnsHostname ; cnf <= ComputerNameDnsFullyQualified ; ++cnf) - { + for (int cnf = ComputerNameDnsHostname ; cnf <= ComputerNameDnsFullyQualified ; ++cnf) { + hostnameLen = sizeof(hostname); - if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) - { + if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) { + const vmime::string hostnameStr(hostname); - if (utility::stringUtils::isValidFQDN(hostnameStr)) + if (utility::stringUtils::isValidFQDN(hostnameStr)) { return hostnameStr; + } } } // Anything else will be OK, as long as it is a valid hostname - for (int cnf = 0 ; cnf < ComputerNameMax ; ++cnf) - { + for (int cnf = 0 ; cnf < ComputerNameMax ; ++cnf) { + hostnameLen = sizeof(hostname); - if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) - { + if (GetComputerNameEx((COMPUTER_NAME_FORMAT) cnf, hostname, &hostnameLen)) { + const vmime::string hostnameStr(hostname); - if (utility::stringUtils::isValidHostname(hostnameStr)) + if (utility::stringUtils::isValidHostname(hostnameStr)) { return hostnameStr; + } } } @@ -238,22 +252,22 @@ const vmime::string windowsHandler::getHostName() const } -unsigned int windowsHandler::getProcessId() const -{ - return (static_cast (::GetCurrentProcessId())); +unsigned int windowsHandler::getProcessId() const { + + return static_cast (::GetCurrentProcessId()); } -unsigned int windowsHandler::getThreadId() const -{ +unsigned int windowsHandler::getThreadId() const { + return static_cast (::GetCurrentThreadId()); } #if VMIME_HAVE_MESSAGING_FEATURES -shared_ptr windowsHandler::getSocketFactory() -{ +shared_ptr windowsHandler::getSocketFactory() { + return m_socketFactory; } @@ -262,14 +276,14 @@ shared_ptr windowsHandler::getSocketFactory() #if VMIME_HAVE_FILESYSTEM_FEATURES -shared_ptr windowsHandler::getFileSystemFactory() -{ +shared_ptr windowsHandler::getFileSystemFactory() { + return m_fileSysFactory; } -shared_ptr windowsHandler::getChildProcessFactory() -{ +shared_ptr windowsHandler::getChildProcessFactory() { + // TODO: Not implemented return null; } @@ -277,8 +291,8 @@ shared_ptr windowsHandler::getChildProcess #endif -void windowsHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) -{ +void windowsHandler::generateRandomBytes(unsigned char* buffer, const unsigned int count) { + HCRYPTPROV cryptProvider = 0; CryptAcquireContext(&cryptProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); CryptGenRandom(cryptProvider, static_cast (count), static_cast (buffer)); @@ -286,8 +300,8 @@ void windowsHandler::generateRandomBytes(unsigned char* buffer, const unsigned i } -shared_ptr windowsHandler::createCriticalSection() -{ +shared_ptr windowsHandler::createCriticalSection() { + return make_shared (); } diff --git a/src/vmime/platforms/windows/windowsHandler.hpp b/src/vmime/platforms/windows/windowsHandler.hpp index b80f0de8..9dda256c 100644 --- a/src/vmime/platforms/windows/windowsHandler.hpp +++ b/src/vmime/platforms/windows/windowsHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,8 +47,8 @@ namespace platforms { namespace windows { -class VMIME_EXPORT windowsHandler : public vmime::platform::handler -{ +class VMIME_EXPORT windowsHandler : public vmime::platform::handler { + public: windowsHandler(); diff --git a/src/vmime/platforms/windows/windowsSocket.cpp b/src/vmime/platforms/windows/windowsSocket.cpp index 2fadc36e..3a93c53a 100644 --- a/src/vmime/platforms/windows/windowsSocket.cpp +++ b/src/vmime/platforms/windows/windowsSocket.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,27 +47,29 @@ namespace windows { // windowsSocket::windowsSocket(shared_ptr th) - : m_timeoutHandler(th), m_desc(INVALID_SOCKET), m_status(0) -{ + : m_timeoutHandler(th), + m_desc(INVALID_SOCKET), + m_status(0) { + WSAData wsaData; WSAStartup(MAKEWORD(1, 1), &wsaData); } -windowsSocket::~windowsSocket() -{ - if (m_desc != INVALID_SOCKET) +windowsSocket::~windowsSocket() { + + if (m_desc != INVALID_SOCKET) { ::closesocket(m_desc); + } WSACleanup(); } -void windowsSocket::connect(const vmime::string& address, const vmime::port_t port) -{ +void windowsSocket::connect(const vmime::string& address, const vmime::port_t port) { + // Close current connection, if any - if (m_desc != INVALID_SOCKET) - { + if (m_desc != INVALID_SOCKET) { ::closesocket(m_desc); m_desc = INVALID_SOCKET; } @@ -81,20 +83,19 @@ void windowsSocket::connect(const vmime::string& address, const vmime::port_t po addr.sin_port = htons(static_cast (port)); addr.sin_addr.s_addr = ::inet_addr(address.c_str()); - if (m_tracer) - { + if (m_tracer) { + std::ostringstream trace; trace << "Connecting to " << address << ", port " << port; m_tracer->traceSend(trace.str()); } - if (addr.sin_addr.s_addr == static_cast (-1)) - { + if (addr.sin_addr.s_addr == static_cast (-1)) { + ::hostent* hostInfo = ::gethostbyname(address.c_str()); - if (hostInfo == NULL) - { + if (!hostInfo) { // Error: cannot resolve address throw vmime::exceptions::connection_error("Cannot resolve address."); } @@ -107,36 +108,34 @@ void windowsSocket::connect(const vmime::string& address, const vmime::port_t po // Get a new socket m_desc = ::socket(AF_INET, SOCK_STREAM, 0); - if (m_desc == INVALID_SOCKET) - { - try - { + if (m_desc == INVALID_SOCKET) { + + try { + int err = WSAGetLastError(); throwSocketError(err); - } - catch (exceptions::socket_exception& e) - { - throw vmime::exceptions::connection_error - ("Error while creating socket.", e); + + } catch (exceptions::socket_exception& e) { + + throw vmime::exceptions::connection_error("Error while creating socket.", e); } } // Start connection - if (::connect(m_desc, reinterpret_cast (&addr), sizeof(addr)) == -1) - { - try - { + if (::connect(m_desc, reinterpret_cast (&addr), sizeof(addr)) == -1) { + + try { + int err = WSAGetLastError(); throwSocketError(err); - } - catch (exceptions::socket_exception& e) - { + + } catch (exceptions::socket_exception& e) { + ::closesocket(m_desc); m_desc = INVALID_SOCKET; // Error - throw vmime::exceptions::connection_error - ("Error while connecting socket.", e); + throw vmime::exceptions::connection_error("Error while connecting socket.", e); } } @@ -146,10 +145,11 @@ void windowsSocket::connect(const vmime::string& address, const vmime::port_t po } -bool windowsSocket::isConnected() const -{ - if (m_desc == INVALID_SOCKET) +bool windowsSocket::isConnected() const { + + if (m_desc == INVALID_SOCKET) { return false; + } char buff; @@ -157,12 +157,13 @@ bool windowsSocket::isConnected() const } -void windowsSocket::disconnect() -{ - if (m_desc != INVALID_SOCKET) - { - if (m_tracer) +void windowsSocket::disconnect() { + + if (m_desc != INVALID_SOCKET) { + + if (m_tracer) { m_tracer->traceSend("Disconnecting"); + } ::shutdown(m_desc, SD_BOTH); ::closesocket(m_desc); @@ -172,28 +173,28 @@ void windowsSocket::disconnect() } -static bool isNumericAddress(const char* address) -{ +static bool isNumericAddress(const char* address) { + struct addrinfo hint, *info = NULL; memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(address, 0, &hint, &info) == 0) - { + if (getaddrinfo(address, 0, &hint, &info) == 0) { + freeaddrinfo(info); return true; - } - else - { + + } else { + return false; } } -const string windowsSocket::getPeerAddress() const -{ +const string windowsSocket::getPeerAddress() const { + // Get address of connected peer sockaddr peer; socklen_t peerLen = sizeof(peer); @@ -206,8 +207,8 @@ const string windowsSocket::getPeerAddress() const if (getnameinfo(reinterpret_cast (&peer), peerLen, host, sizeof(host), service, sizeof(service), - /* flags */ NI_NUMERICHOST) == 0) - { + /* flags */ NI_NUMERICHOST) == 0) { + return string(host); } @@ -215,8 +216,8 @@ const string windowsSocket::getPeerAddress() const } -const string windowsSocket::getPeerName() const -{ +const string windowsSocket::getPeerName() const { + // Get address of connected peer sockaddr peer; socklen_t peerLen = sizeof(peer); @@ -225,15 +226,15 @@ const string windowsSocket::getPeerName() const // If server address as specified when connecting is a numeric // address, try to get a host name for it - if (isNumericAddress(m_serverAddress.c_str())) - { + if (isNumericAddress(m_serverAddress.c_str())) { + char host[NI_MAXHOST + 1]; char service[NI_MAXSERV + 1]; if (getnameinfo(reinterpret_cast (&peer), peerLen, host, sizeof(host), service, sizeof(service), - /* flags */ NI_NAMEREQD) == 0) - { + /* flags */ NI_NAMEREQD) == 0) { + return string(host); } } @@ -242,38 +243,38 @@ const string windowsSocket::getPeerName() const } -size_t windowsSocket::getBlockSize() const -{ +size_t windowsSocket::getBlockSize() const { + return 16384; // 16 KB } -void windowsSocket::receive(vmime::string& buffer) -{ +void windowsSocket::receive(vmime::string& buffer) { + const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size); } -size_t windowsSocket::receiveRaw(byte_t* buffer, const size_t count) -{ +size_t windowsSocket::receiveRaw(byte_t* buffer, const size_t count) { + m_status &= ~STATUS_WOULDBLOCK; // Check whether data is available - if (!waitForRead(50 /* msecs */)) - { + if (!waitForRead(50 /* msecs */)) { + // No data available at this time // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Server did not react within timeout delay throwSocketError(WSAETIMEDOUT); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -286,101 +287,105 @@ size_t windowsSocket::receiveRaw(byte_t* buffer, const size_t count) // Read available data int ret = ::recv(m_desc, reinterpret_cast (buffer), count, 0); - if (ret == SOCKET_ERROR) - { + if (ret == SOCKET_ERROR) { + int err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) + if (err != WSAEWOULDBLOCK) { throwSocketError(err); + } m_status |= STATUS_WOULDBLOCK; // Error or no data - return (0); - } - else if (ret == 0) - { + return 0; + + } else if (ret == 0) { + // Host shutdown throwSocketError(WSAENOTCONN); - } - else - { + + } else { + // Data received, reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } return ret; } } -void windowsSocket::send(const vmime::string& buffer) -{ +void windowsSocket::send(const vmime::string& buffer) { + sendRaw(reinterpret_cast (buffer.data()), buffer.length()); } -void windowsSocket::send(const char* str) -{ +void windowsSocket::send(const char* str) { + sendRaw(reinterpret_cast (str), strlen(str)); } -void windowsSocket::sendRaw(const byte_t* buffer, const size_t count) -{ +void windowsSocket::sendRaw(const byte_t* buffer, const size_t count) { + m_status &= ~STATUS_WOULDBLOCK; size_t size = count; - while (size > 0) - { + while (size > 0) { + const int ret = ::send(m_desc, reinterpret_cast (buffer), size, 0); - if (ret == SOCKET_ERROR) - { + if (ret == SOCKET_ERROR) { + int err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) + if (err != WSAEWOULDBLOCK) { throwSocketError(err); + } waitForWrite(50 /* msecs */); - } - else - { + + } else { + buffer += ret; size -= ret; } } // Reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } } -size_t windowsSocket::sendRawNonBlocking(const byte_t* 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, reinterpret_cast (buffer), count, 0); - if (ret == SOCKET_ERROR) - { + if (ret == SOCKET_ERROR) { + int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) - { + if (err == WSAEWOULDBLOCK) { + // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Could not send data within timeout delay throwSocketError(err); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -390,29 +395,30 @@ size_t windowsSocket::sendRawNonBlocking(const byte_t* buffer, const size_t coun // No data can be written at this time return 0; - } - else - { + + } else { + throwSocketError(err); } } // Reset timeout - if (m_timeoutHandler) + if (m_timeoutHandler) { m_timeoutHandler->resetTimeOut(); + } return ret; } -unsigned int windowsSocket::getStatus() const -{ +unsigned int windowsSocket::getStatus() const { + return m_status; } -void windowsSocket::throwSocketError(const int err) -{ +void windowsSocket::throwSocketError(const int err) { + std::ostringstream oss; string msg; @@ -420,13 +426,13 @@ void windowsSocket::throwSocketError(const int err) if (::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, err, 0, (LPTSTR) &str, 0, NULL) == 0) - { + NULL, err, 0, (LPTSTR) &str, 0, NULL) == 0) { + // Failed getting message oss << "Unknown socket error (code " << err << ")"; - } - else - { + + } else { + oss << str; ::LocalFree(str); } @@ -437,10 +443,10 @@ void windowsSocket::throwSocketError(const int err) } -bool windowsSocket::waitForData(const bool read, const bool write, const int msecs) -{ - for (int i = 0 ; i <= msecs / 10 ; ++i) - { +bool windowsSocket::waitForData(const bool read, const bool write, const int msecs) { + + for (int i = 0 ; i <= msecs / 10 ; ++i) { + // Check whether data is available fd_set fds; FD_ZERO(&fds); @@ -452,28 +458,28 @@ bool windowsSocket::waitForData(const bool read, const bool write, const int mse int ret = ::select(m_desc + 1, read ? &fds : NULL, write ? &fds : NULL, NULL, &tv); - if (ret == SOCKET_ERROR) - { + if (ret == SOCKET_ERROR) { + int err = WSAGetLastError(); throwSocketError(err); - } - else if (ret > 0) - { + + } else if (ret > 0) { + return true; } // No data available at this time // Check if we are timed out if (m_timeoutHandler && - m_timeoutHandler->isTimeOut()) - { - if (!m_timeoutHandler->handleTimeOut()) - { + m_timeoutHandler->isTimeOut()) { + + if (!m_timeoutHandler->handleTimeOut()) { + // Server did not react within timeout delay throw exceptions::operation_timed_out(); - } - else - { + + } else { + // Reset timeout m_timeoutHandler->resetTimeOut(); } @@ -484,32 +490,32 @@ bool windowsSocket::waitForData(const bool read, const bool write, const int mse } -bool windowsSocket::waitForRead(const int msecs) -{ +bool windowsSocket::waitForRead(const int msecs) { + return waitForData(/* read */ true, /* write */ false, msecs); } -bool windowsSocket::waitForWrite(const int msecs) -{ +bool windowsSocket::waitForWrite(const int msecs) { + return waitForData(/* read */ false, /* write */ true, msecs); } -shared_ptr windowsSocket::getTimeoutHandler() -{ +shared_ptr windowsSocket::getTimeoutHandler() { + return m_timeoutHandler; } -void windowsSocket::setTracer(const shared_ptr & tracer) -{ +void windowsSocket::setTracer(const shared_ptr & tracer) { + m_tracer = tracer; } -shared_ptr windowsSocket::getTracer() -{ +shared_ptr windowsSocket::getTracer() { + return m_tracer; } @@ -519,17 +525,19 @@ shared_ptr windowsSocket::getTracer() // posixSocketFactory // -shared_ptr windowsSocketFactory::create() -{ +shared_ptr windowsSocketFactory::create() { + shared_ptr th; return make_shared (th); } -shared_ptr windowsSocketFactory::create(const shared_ptr & th) -{ + +shared_ptr windowsSocketFactory::create(const shared_ptr & th) { + return make_shared (th); } + } // posix } // platforms } // vmime diff --git a/src/vmime/platforms/windows/windowsSocket.hpp b/src/vmime/platforms/windows/windowsSocket.hpp index 84fbdfc0..ddb82da5 100644 --- a/src/vmime/platforms/windows/windowsSocket.hpp +++ b/src/vmime/platforms/windows/windowsSocket.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ namespace platforms { namespace windows { -class windowsSocket : public vmime::net::socket -{ +class windowsSocket : public vmime::net::socket { + public: windowsSocket(); @@ -98,8 +98,8 @@ private: -class windowsSocketFactory : public vmime::net::socketFactory -{ +class windowsSocketFactory : public vmime::net::socketFactory { + public: shared_ptr create(); diff --git a/src/vmime/propertySet.cpp b/src/vmime/propertySet.cpp index c22e79a6..e0d48488 100644 --- a/src/vmime/propertySet.cpp +++ b/src/vmime/propertySet.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,82 +25,87 @@ #include "vmime/parserHelpers.hpp" -namespace vmime -{ +namespace vmime { -propertySet::propertySet() -{ +propertySet::propertySet() { + } -propertySet::propertySet(const string& props) -{ +propertySet::propertySet(const string& props) { + parse(props); } propertySet::propertySet(const propertySet& set) - : object() -{ - for (std::list >::const_iterator it = set.m_props.begin() ; it != set.m_props.end() ; ++it) + : object() { + + for (std::list >::const_iterator it = set.m_props.begin() ; + it != set.m_props.end() ; ++it) { + m_props.push_back(make_shared (**it)); + } } -propertySet::~propertySet() -{ +propertySet::~propertySet() { + removeAllProperties(); } -propertySet& propertySet::operator=(const propertySet& set) -{ +propertySet& propertySet::operator=(const propertySet& set) { + removeAllProperties(); - for (std::list >::const_iterator it = set.m_props.begin() ; it != set.m_props.end() ; ++it) - m_props.push_back(make_shared (**it)); + for (std::list >::const_iterator it = set.m_props.begin() ; + it != set.m_props.end() ; ++it) { - return (*this); + m_props.push_back(make_shared (**it)); + } + + return *this; } -void propertySet::setFromString(const string& props) -{ +void propertySet::setFromString(const string& props) { + parse(props); } -void propertySet::removeAllProperties() -{ +void propertySet::removeAllProperties() { + m_props.clear(); } -void propertySet::removeProperty(const string& name) -{ - std::list >::iterator it = std::find_if - (m_props.begin(), m_props.end(), propFinder(name)); +void propertySet::removeProperty(const string& name) { - if (it != m_props.end()) + std::list >::iterator it = + std::find_if(m_props.begin(), m_props.end(), propFinder(name)); + + if (it != m_props.end()) { m_props.erase(it); + } } -void propertySet::parse(const string& props) -{ +void propertySet::parse(const string& props) { + const string::const_iterator end = props.end(); string::const_iterator pos = props.begin(); - for ( ; pos != end ; ) - { + for ( ; pos != end ; ) { + // Skip white-spaces for ( ; pos != end && parserHelpers::isSpace(*pos) ; ++pos) {} - if (pos != end) - { - if (*pos == ';') - { + if (pos != end) { + + if (*pos == ';') { ++pos; continue; } @@ -117,48 +122,50 @@ void propertySet::parse(const string& props) const string option(optStart, optEnd); string value = "1"; - if (pos != end) - { + if (pos != end) { + ++pos; // skip '=' // Extract the value for ( ; pos != end && parserHelpers::isSpace(*pos) ; ++pos) {} - if (pos != end) - { + if (pos != end) { + // A quoted-string - if (*pos == '"' || *pos == '\'') - { + if (*pos == '"' || *pos == '\'') { + value.reserve(50); const char quoteChar = *pos; bool theEnd = false; bool escape = false; - for ( ; (pos != end) && !theEnd ; ++pos) - { - if (escape) - { + for ( ; (pos != end) && !theEnd ; ++pos) { + + if (escape) { + value += *pos; escape = false; - } - else - { - if (*pos == '\\') + + } else { + + if (*pos == '\\') { escape = true; - else if (*pos == quoteChar) + } else if (*pos == quoteChar) { theEnd = true; - else + } else { value += *pos; + } } } - if (pos != end) + if (pos != end) { ++pos; - } + } + // Simple value - else - { + } else { + const string::const_iterator valStart = pos; for ( ; pos != end && !parserHelpers::isSpace(*pos) ; ++pos) {} @@ -169,8 +176,9 @@ void propertySet::parse(const string& props) // Advance to the next ';' for ( ; pos != end && (*pos != ';') ; ++pos) {} - if (pos != end) + if (pos != end) { ++pos; // skip ';' + } } } @@ -180,70 +188,72 @@ void propertySet::parse(const string& props) } -shared_ptr propertySet::find(const string& name) const -{ - std::list >::const_iterator it = std::find_if - (m_props.begin(), m_props.end(), propFinder(name)); +shared_ptr propertySet::find(const string& name) const { - return (it != m_props.end() ? *it : null); + std::list >::const_iterator it = + std::find_if(m_props.begin(), m_props.end(), propFinder(name)); + + return it != m_props.end() ? *it : null; } -shared_ptr propertySet::findOrCreate(const string& name) -{ - std::list >::const_iterator it = std::find_if - (m_props.begin(), m_props.end(), propFinder(name)); +shared_ptr propertySet::findOrCreate(const string& name) { + + std::list >::const_iterator it = + std::find_if(m_props.begin(), m_props.end(), propFinder(name)); + + if (it != m_props.end()) { + + return *it; + + } else { - if (it != m_props.end()) - { - return (*it); - } - else - { shared_ptr prop = make_shared (name, ""); m_props.push_back(prop); - return (prop); + return prop; } } -propertySet::propertyProxy propertySet::operator[](const string& name) -{ - return (propertyProxy(name, this)); +propertySet::propertyProxy propertySet::operator[](const string& name) { + + return propertyProxy(name, this); } -const propertySet::constPropertyProxy propertySet::operator[](const string& name) const -{ - return (constPropertyProxy(name, this)); +const propertySet::constPropertyProxy propertySet::operator[](const string& name) const { + + return constPropertyProxy(name, this); } -bool propertySet::hasProperty(const string& name) const -{ - return (find(name) != NULL); +bool propertySet::hasProperty(const string& name) const { + + return find(name) != NULL; } -const std::vector > propertySet::getPropertyList() const -{ +const std::vector > propertySet::getPropertyList() const { + std::vector > res; - for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) + for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) { res.push_back(*it); + } - return (res); + return res; } -const std::vector > propertySet::getPropertyList() -{ +const std::vector > propertySet::getPropertyList() { + std::vector > res; - for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) + for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) { res.push_back(*it); + } - return (res); + return res; } @@ -252,40 +262,43 @@ const std::vector > propertySet::getProperty // propertySet::property::property(const string& name, const string& value) - : m_name(name), m_value(value) -{ + : m_name(name), + m_value(value) { + } propertySet::property::property(const string& name) - : m_name(name) -{ + : m_name(name) { + } propertySet::property::property(const property& prop) - : object(), m_name(prop.m_name), m_value(prop.m_value) -{ + : object(), + m_name(prop.m_name), + m_value(prop.m_value) { + } -const string& propertySet::property::getName() const -{ - return (m_name); +const string& propertySet::property::getName() const { + + return m_name; } #ifndef _MSC_VER -const string& propertySet::property::getValue() const -{ - return (m_value); +const string& propertySet::property::getValue() const { + + return m_value; } -void propertySet::property::setValue(const string& value) -{ +void propertySet::property::setValue(const string& value) { + m_value = value; } @@ -296,33 +309,35 @@ void propertySet::property::setValue(const string& value) #ifndef VMIME_INLINE_TEMPLATE_SPECIALIZATION template <> -void propertySet::property::setValue(const string& value) -{ +void propertySet::property::setValue(const string& value) { + m_value = value; } template <> -void propertySet::property::setValue(const bool& value) -{ +void propertySet::property::setValue(const bool& value) { + m_value = value ? "true" : "false"; } template <> -string propertySet::property::getValue() const -{ - return (m_value); +string propertySet::property::getValue() const { + + return m_value; } template <> -bool propertySet::property::getValue() const -{ - if (utility::stringUtils::toLower(m_value) == "true") +bool propertySet::property::getValue() const { + + if (utility::stringUtils::toLower(m_value) == "true") { + return true; - else - { + + } else { + int val = 0; std::istringstream iss(m_value); @@ -330,7 +345,7 @@ bool propertySet::property::getValue() const iss >> val; - return (!iss.fail() && val != 0); + return !iss.fail() && val != 0; } } @@ -338,26 +353,28 @@ bool propertySet::property::getValue() const template <> -string propertySet::valueFromString(const string& value) -{ +string propertySet::valueFromString(const string& value) { + return value; } template <> -string propertySet::valueToString(const string& value) -{ +string propertySet::valueToString(const string& value) { + return value; } template <> -bool propertySet::valueFromString(const string& value) -{ - if (utility::stringUtils::toLower(value) == "true") +bool propertySet::valueFromString(const string& value) { + + if (utility::stringUtils::toLower(value) == "true") { + return true; - else - { + + } else { + int val = 0; std::istringstream iss(value); @@ -365,15 +382,15 @@ bool propertySet::valueFromString(const string& value) iss >> val; - return (!iss.fail() && val != 0); + return !iss.fail() && val != 0; } } template <> -string propertySet::valueToString(const bool& value) -{ - return (value ? "true" : "false"); +string propertySet::valueToString(const bool& value) { + + return value ? "true" : "false"; } #endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION diff --git a/src/vmime/propertySet.hpp b/src/vmime/propertySet.hpp index fb22b437..681097d9 100644 --- a/src/vmime/propertySet.hpp +++ b/src/vmime/propertySet.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,21 +36,19 @@ #include "vmime/utility/stringUtils.hpp" -namespace vmime -{ +namespace vmime { /** Manage a list of (name,value) pairs. */ +class VMIME_EXPORT propertySet : public object { -class VMIME_EXPORT propertySet : public object -{ public: /** A property holds a (name,value) pair. */ - class property : public object - { + class property : public object { + public: property(const string& name, const string& value); @@ -86,8 +84,8 @@ public: * * @param value new value for property */ - template void setValue(const TYPE& value) - { + template void setValue(const TYPE& value) { + std::ostringstream oss; oss.imbue(std::locale::classic()); // no formatting @@ -103,8 +101,8 @@ public: * converted using std::istringstream) * @return current value of the property */ - template TYPE getValue() const - { + template TYPE getValue() const { + TYPE val = TYPE(); std::istringstream iss(m_value); @@ -112,8 +110,9 @@ public: iss >> val; - if (iss.fail()) + if (iss.fail()) { throw exceptions::invalid_property_type(); + } return (val); } @@ -122,30 +121,32 @@ public: #ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION template <> - void propertySet::property::setValue(const string& value) - { + void propertySet::property::setValue(const string& value) { + m_value = value; } template <> - void propertySet::property::setValue(const bool& value) - { + void propertySet::property::setValue(const bool& value) { + m_value = value ? "true" : "false"; } template <> - string propertySet::property::getValue() const - { + string propertySet::property::getValue() const { + return (m_value); } template <> - bool propertySet::property::getValue() const - { - if (utility::stringUtils::toLower(m_value) == "true") + bool propertySet::property::getValue() const { + + if (utility::stringUtils::toLower(m_value) == "true") { + return true; - else - { + + } else { + int val = 0; std::istringstream iss(m_value); @@ -153,7 +154,7 @@ public: iss >> val; - return (!iss.fail() && val != 0); + return !iss.fail() && val != 0; } } @@ -167,37 +168,38 @@ public: protected: - class propertyProxy - { + class propertyProxy { + public: propertyProxy(const string& name, propertySet* set) - : m_name(name), m_set(set) - { + : m_name(name), + m_set(set) { + } template - propertyProxy& operator=(const TYPE& value) - { + propertyProxy& operator=(const TYPE& value) { + m_set->setProperty(m_name, value); - return (*this); + return *this; } template - void setValue(const TYPE& value) - { + void setValue(const TYPE& value) { + m_set->setProperty(m_name, value); } template - const TYPE getValue() const - { - return (m_set->getProperty (m_name)); + const TYPE getValue() const { + + return m_set->getProperty (m_name); } - operator string() const - { - return (m_set->getProperty (m_name)); + operator string() const { + + return m_set->getProperty (m_name); } private: @@ -206,24 +208,25 @@ protected: propertySet* m_set; }; - class constPropertyProxy - { + class constPropertyProxy { + public: constPropertyProxy(const string& name, const propertySet* set) - : m_name(name), m_set(set) - { + : m_name(name), + m_set(set) { + } template - const TYPE getValue() const - { - return (m_set->getProperty (m_name)); + const TYPE getValue() const { + + return m_set->getProperty (m_name); } - operator string() const - { - return (m_set->getProperty (m_name)); + operator string() const { + + return m_set->getProperty (m_name); } private: @@ -274,12 +277,11 @@ public: * @return value of the specified property */ template - const TYPE getProperty(const string& name) const - { + const TYPE getProperty(const string& name) const { + const shared_ptr prop = find(name); if (!prop) throw exceptions::no_such_property(name); - //return (prop->getValue ()); // BUG: with g++ < 3.4 return (prop->template getValue ()); } @@ -293,11 +295,10 @@ public: * if if does not exist */ template - const TYPE getProperty(const string& name, const TYPE defaultValue) const - { + const TYPE getProperty(const string& name, const TYPE defaultValue) const { + const shared_ptr prop = find(name); - //return (prop ? prop->getValue () : defaultValue); // BUG: with g++ < 3.4 - return (prop ? prop->template getValue () : defaultValue); + return prop ? prop->template getValue () : defaultValue; } /** Change the value of the specified property or create @@ -307,8 +308,8 @@ public: * @param value property value */ template - void setProperty(const string& name, const TYPE& value) - { + void setProperty(const string& name, const TYPE& value) { + findOrCreate(name)->setValue(value); } @@ -335,14 +336,14 @@ private: void parse(const string& props); - class propFinder : public std::unary_function , bool> - { + class propFinder : public std::unary_function , bool> { + public: propFinder(const string& name) : m_name(utility::stringUtils::toLower(name)) { } - bool operator()(const shared_ptr & p) const - { + bool operator()(const shared_ptr & p) const { + return (utility::stringUtils::toLower(p->getName()) == m_name); } @@ -360,8 +361,8 @@ private: public: template - static TYPE valueFromString(const string& value) - { + static TYPE valueFromString(const string& value) { + TYPE v = TYPE(); std::istringstream iss(value); @@ -373,8 +374,8 @@ public: } template - static string valueToString(const TYPE& value) - { + static string valueToString(const TYPE& value) { + std::ostringstream oss(value); oss.imbue(std::locale::classic()); // no formatting @@ -386,24 +387,26 @@ public: #ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION template <> - static string valueFromString(const string& value) - { + static string valueFromString(const string& value) { + return value; } template <> - static string valueToString(const string& value) - { + static string valueToString(const string& value) { + return value; } template <> - static bool valueFromString(const string& value) - { - if (utility::stringUtils::toLower(value) == "true") + static bool valueFromString(const string& value) { + + if (utility::stringUtils::toLower(value) == "true") { + return true; - else - { + + } else { + int val = 0; std::istringstream iss(value); @@ -411,14 +414,14 @@ public: iss >> val; - return (!iss.fail() && val != 0); + return !iss.fail() && val != 0; } } template <> - static string valueToString(const bool& value) - { - return (value ? "true" : "false"); + static string valueToString(const bool& value) { + + return value ? "true" : "false"; } #endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION diff --git a/src/vmime/relay.cpp b/src/vmime/relay.cpp index 2f4cf350..b0a6b60f 100644 --- a/src/vmime/relay.cpp +++ b/src/vmime/relay.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,18 +29,17 @@ #include -namespace vmime -{ +namespace vmime { -relay::relay() -{ +relay::relay() { + } relay::relay(const relay& r) - : headerFieldValue() -{ + : headerFieldValue() { + copyFrom(r); } @@ -58,34 +57,39 @@ relay::relay(const relay& r) ["for" addr-spec] ; initial form */ -void relay::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void relay::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + const char* const pend = buffer.data() + end; const char* const pstart = buffer.data() + position; const char* p = pend - 1; // Find the beginning of the date part - while (p >= pstart && *p != ';') + while (p >= pstart && *p != ';') { --p; + } + + if (p >= pstart) { - if (p >= pstart) - { // Parse the date/time part m_date.parse(ctx, buffer, position + (p - pstart) + 1, end); // Parse the components - std::istringstream iss(string - (buffer.begin() + position, buffer.begin() + position + (p - pstart))); + std::istringstream iss( + string(buffer.begin() + position, buffer.begin() + position + (p - pstart)) + ); iss.imbue(std::locale::classic()); string word; std::vector previous; - enum Parts - { + enum Parts { Part_None, Part_From, // The "from" part Part_By, // The "by" part @@ -100,19 +104,19 @@ void relay::parseImpl bool cont = true; bool inComment = false; - while (cont) - { + while (cont) { + Parts newPart = Part_None; - if ((cont = !(iss >> word).fail())) - { + if ((cont = !(iss >> word).fail())) { + // A little hack for handling comments - if (inComment) - { + if (inComment) { + size_t par = word.find(')'); - if (par != string::npos) - { + if (par != string::npos) { + previous.push_back(string(word.begin(), word.begin() + par + 1)); word.erase(word.begin(), word.begin() + par + 1); inComment = false; @@ -121,71 +125,71 @@ void relay::parseImpl bool keyword = false; - if (!inComment) - { - if (utility::stringUtils::isStringEqualNoCase(word, "from", 4)) - { + if (!inComment) { + + if (utility::stringUtils::isStringEqualNoCase(word, "from", 4)) { + newPart = Part_From; keyword = true; - } - else if (utility::stringUtils::isStringEqualNoCase(word, "by", 2)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(word, "by", 2)) { + newPart = Part_By; keyword = true; - } - else if (utility::stringUtils::isStringEqualNoCase(word, "via", 2)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(word, "via", 2)) { + newPart = Part_Via; keyword = true; - } - else if (utility::stringUtils::isStringEqualNoCase(word, "with", 2)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(word, "with", 2)) { + newPart = Part_With; keyword = true; - } - else if (utility::stringUtils::isStringEqualNoCase(word, "id", 2)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(word, "id", 2)) { + newPart = Part_Id; keyword = true; - } - else if (utility::stringUtils::isStringEqualNoCase(word, "for", 2)) - { + + } else if (utility::stringUtils::isStringEqualNoCase(word, "for", 2)) { + newPart = Part_For; keyword = true; } } - if (!keyword) - { - if (word.find('(') != string::npos) + if (!keyword) { + + if (word.find('(') != string::npos) { inComment = true; + } previous.push_back(word); } } - if (!cont || newPart != Part_None) - { - if (part != Part_None) - { + if (!cont || newPart != Part_None) { + + if (part != Part_None) { + std::ostringstream value; for (std::vector ::const_iterator - it = previous.begin() ; it != previous.end() ; ++it) - { + it = previous.begin() ; it != previous.end() ; ++it) { + if (it != previous.begin()) value << " "; value << *it; } - switch (part) - { - case Part_From: m_from = value.str(); break; - case Part_By: m_by = value.str(); break; - case Part_Via: m_via = value.str(); break; - case Part_With: m_with.push_back(value.str()); break; - case Part_Id: m_id = value.str(); break; - case Part_For: m_for = value.str(); break; - default: break; // Should never happen... + switch (part) { + case Part_From: m_from = value.str(); break; + case Part_By: m_by = value.str(); break; + case Part_Via: m_via = value.str(); break; + case Part_With: m_with.push_back(value.str()); break; + case Part_Id: m_id = value.str(); break; + case Part_For: m_for = value.str(); break; + default: break; // Should never happen... } } @@ -197,15 +201,19 @@ void relay::parseImpl setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void relay::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void relay::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + std::ostringstream oss; int count = 0; @@ -214,8 +222,8 @@ void relay::generateImpl if (m_via.length()) oss << (count++ > 0 ? " " : "") << "via " << m_via; for (std::vector ::const_iterator - it = m_with.begin() ; it != m_with.end() ; ++it) - { + it = m_with.begin() ; it != m_with.end() ; ++it) { + oss << (count++ > 0 ? " " : "") << "with " << *it; } @@ -227,13 +235,12 @@ void relay::generateImpl vmime::utility::outputStreamAdapter dos(oss); m_date.generate(ctx, dos, 0, NULL); - text(oss.str()).encodeAndFold(ctx, os, - curLinePos, newLinePos, text::FORCE_NO_ENCODING); + text(oss.str()).encodeAndFold(ctx, os, curLinePos, newLinePos, text::FORCE_NO_ENCODING); } -void relay::copyFrom(const component& other) -{ +void relay::copyFrom(const component& other) { + const relay& r = dynamic_cast (other); m_from = r.m_from; @@ -249,105 +256,105 @@ void relay::copyFrom(const component& other) } -relay& relay::operator=(const relay& other) -{ +relay& relay::operator=(const relay& other) { + copyFrom(other); - return (*this); + return *this; } -shared_ptr relay::clone() const -{ +shared_ptr relay::clone() const { + return make_shared (*this); } -const string& relay::getFrom() const -{ - return (m_from); +const string& relay::getFrom() const { + + return m_from; } -void relay::setFrom(const string& from) -{ +void relay::setFrom(const string& from) { + m_from = from; } -const string& relay::getVia() const -{ - return (m_via); +const string& relay::getVia() const { + + return m_via; } -void relay::setVia(const string& via) -{ +void relay::setVia(const string& via) { + m_via = via; } -const string& relay::getBy() const -{ - return (m_by); +const string& relay::getBy() const { + + return m_by; } -void relay::setBy(const string& by) -{ +void relay::setBy(const string& by) { + m_by = by; } -const string& relay::getId() const -{ - return (m_id); +const string& relay::getId() const { + + return m_id; } -void relay::setId(const string& id) -{ +void relay::setId(const string& id) { + m_id = id; } -const string& relay::getFor() const -{ - return (m_for); +const string& relay::getFor() const { + + return m_for; } -void relay::setFor(const string& for_) -{ +void relay::setFor(const string& for_) { + m_for = for_; } -const datetime& relay::getDate() const -{ - return (m_date); +const datetime& relay::getDate() const { + + return m_date; } -void relay::setDate(const datetime& date) -{ +void relay::setDate(const datetime& date) { + m_date = date; } -const std::vector & relay::getWithList() const -{ - return (m_with); +const std::vector & relay::getWithList() const { + + return m_with; } -std::vector & relay::getWithList() -{ - return (m_with); +std::vector & relay::getWithList() { + + return m_with; } -const std::vector > relay::getChildComponents() -{ +const std::vector > relay::getChildComponents() { + // TODO: should fields inherit from 'component'? (using typeAdapter) return std::vector >(); } diff --git a/src/vmime/relay.hpp b/src/vmime/relay.hpp index 35949ff1..f4676026 100644 --- a/src/vmime/relay.hpp +++ b/src/vmime/relay.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,15 +31,13 @@ #include "vmime/dateTime.hpp" -namespace vmime -{ +namespace vmime { /** Trace information about a relay (basic type). */ +class VMIME_EXPORT relay : public headerFieldValue { -class VMIME_EXPORT relay : public headerFieldValue -{ public: relay(); @@ -87,18 +85,20 @@ private: protected: - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; }; diff --git a/src/vmime/security/authenticator.hpp b/src/vmime/security/authenticator.hpp index c73229dd..03bca733 100644 --- a/src/vmime/security/authenticator.hpp +++ b/src/vmime/security/authenticator.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -60,8 +60,8 @@ namespace security { * WARNING: an authenticator should be used with one and ONLY ONE messaging * service at a time. */ -class VMIME_EXPORT authenticator : public object -{ +class VMIME_EXPORT authenticator : public object { + public: /** Return the authentication identity (usually, this @@ -134,4 +134,3 @@ public: #endif // VMIME_HAVE_MESSAGING_FEATURES #endif // VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED - diff --git a/src/vmime/security/cert/X509Certificate.cpp b/src/vmime/security/cert/X509Certificate.cpp index e4b14682..128fac17 100644 --- a/src/vmime/security/cert/X509Certificate.cpp +++ b/src/vmime/security/cert/X509Certificate.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,24 +38,24 @@ namespace security { namespace cert { -X509Certificate::~X509Certificate() -{ +X509Certificate::~X509Certificate() { + } -void X509Certificate::checkValidity() -{ +void X509Certificate::checkValidity() { + const datetime now = datetime::now(); - if (now < getActivationDate()) - { + if (now < getActivationDate()) { + certificateNotYetValidException ex; ex.setCertificate(dynamicCast (shared_from_this())); throw ex; - } - else if (now > getExpirationDate()) - { + + } else if (now > getExpirationDate()) { + certificateExpiredException ex; ex.setCertificate(dynamicCast (shared_from_this())); diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp index acf4ae21..5434b45e 100644 --- a/src/vmime/security/cert/X509Certificate.hpp +++ b/src/vmime/security/cert/X509Certificate.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,22 +47,20 @@ namespace cert { /** Identity certificate based on X.509 standard. */ -class VMIME_EXPORT X509Certificate : public certificate -{ +class VMIME_EXPORT X509Certificate : public certificate { + public: ~X509Certificate(); /** Supported encodings for X.509 certificates. */ - enum Format - { + enum Format { FORMAT_DER, /**< DER encoding */ FORMAT_PEM /**< PEM encoding */ }; /** Supported digest algorithms (used for fingerprint). */ - enum DigestAlgorithm - { + enum DigestAlgorithm { DIGEST_MD5, /**< MD5 digest */ DIGEST_SHA1 /**< SHA1 digest */ }; @@ -85,22 +83,27 @@ public: */ static shared_ptr import(const byte_t* data, const size_t length); - /** Imports a DER or PEM encoded X.509 certificate. + /** Import sveral DER or PEM encoded X.509 certificates. * * @param is input stream to read data from * @param certs the resulting list of certificates */ - static void import(utility::inputStream& is, - std::vector >& certs); + static void import( + utility::inputStream& is, + std::vector >& certs + ); - /** Imports a DER or PEM encoded X.509 certificate. + /** Import several DER or PEM encoded X.509 certificates. * * @param data points to raw data * @param length size of data * @param certs the resulting list of certificates */ - static void import(const byte_t* data, const size_t length, - std::vector >& certs); + static void import( + const byte_t* data, + const size_t length, + std::vector >& certs + ); /** Exports this X.509 certificate to the specified format. * @@ -147,9 +150,10 @@ public: * not match the identities in the certificate * @return true if the match is successful, false otherwise */ - virtual bool verifyHostName - (const string& hostname, - std::vector * nonMatchingNames = NULL) const = 0; + virtual bool verifyHostName( + const string& hostname, + std::vector * nonMatchingNames = NULL + ) const = 0; /** Gets the expiration date of this certificate. This is the date * at which this certificate will not be valid anymore. diff --git a/src/vmime/security/cert/certificate.hpp b/src/vmime/security/cert/certificate.hpp index 9d17ad8b..ed0f175b 100644 --- a/src/vmime/security/cert/certificate.hpp +++ b/src/vmime/security/cert/certificate.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ namespace cert { /** Identity certificate for a peer. */ -class VMIME_EXPORT certificate : public object, public enable_shared_from_this -{ +class VMIME_EXPORT certificate : public object, public enable_shared_from_this { + public: /** Returns the encoded form of this certificate (for example, diff --git a/src/vmime/security/cert/certificateChain.cpp b/src/vmime/security/cert/certificateChain.cpp index 1731f873..c506913a 100644 --- a/src/vmime/security/cert/certificateChain.cpp +++ b/src/vmime/security/cert/certificateChain.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,19 +30,19 @@ namespace cert { certificateChain::certificateChain(const std::vector >& certs) - : m_certs(certs) -{ + : m_certs(certs) { + } -size_t certificateChain::getCount() const -{ +size_t certificateChain::getCount() const { + return m_certs.size(); } -const shared_ptr & certificateChain::getAt(const size_t index) -{ +const shared_ptr & certificateChain::getAt(const size_t index) { + return m_certs[index]; } diff --git a/src/vmime/security/cert/certificateChain.hpp b/src/vmime/security/cert/certificateChain.hpp index 7846a200..f8c363e8 100644 --- a/src/vmime/security/cert/certificateChain.hpp +++ b/src/vmime/security/cert/certificateChain.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,8 +38,8 @@ namespace cert { /** An ordered list of certificates, from the subject certificate to * the issuer certificate. */ -class VMIME_EXPORT certificateChain : public object -{ +class VMIME_EXPORT certificateChain : public object { + public: /** Construct a new certificateChain object given an ordered list diff --git a/src/vmime/security/cert/certificateException.cpp b/src/vmime/security/cert/certificateException.cpp index c28a13fe..51a4f03b 100644 --- a/src/vmime/security/cert/certificateException.cpp +++ b/src/vmime/security/cert/certificateException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,42 +36,42 @@ namespace cert { certificateException::certificateException() - : exception("A problem occurred with a certificate.") -{ + : exception("A problem occurred with a certificate.") { + } certificateException::certificateException(const std::string& what) - : exception(what) -{ + : exception(what) { + } -certificateException::~certificateException() throw() -{ +certificateException::~certificateException() throw() { + } -exception* certificateException::clone() const -{ +exception* certificateException::clone() const { + return new certificateException(what()); } -void certificateException::setCertificate(const shared_ptr & cert) -{ +void certificateException::setCertificate(const shared_ptr & cert) { + m_cert = cert; } -shared_ptr certificateException::getCertificate() -{ +shared_ptr certificateException::getCertificate() { + return m_cert; } -shared_ptr certificateException::getCertificate() const -{ +shared_ptr certificateException::getCertificate() const { + return m_cert; } diff --git a/src/vmime/security/cert/certificateException.hpp b/src/vmime/security/cert/certificateException.hpp index fc4ea520..9dd5443b 100644 --- a/src/vmime/security/cert/certificateException.hpp +++ b/src/vmime/security/cert/certificateException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown to indicate a problem with a certificate or certificate verification. */ -class VMIME_EXPORT certificateException : public exception -{ +class VMIME_EXPORT certificateException : public exception { + public: /** Constructs a certificateException with no detail message. diff --git a/src/vmime/security/cert/certificateExpiredException.cpp b/src/vmime/security/cert/certificateExpiredException.cpp index c450f6be..1aa248ec 100644 --- a/src/vmime/security/cert/certificateExpiredException.cpp +++ b/src/vmime/security/cert/certificateExpiredException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,8 +36,8 @@ namespace cert { certificateExpiredException::certificateExpiredException() - : certificateException("The certificate has expired.") -{ + : certificateException("The certificate has expired.") { + } diff --git a/src/vmime/security/cert/certificateExpiredException.hpp b/src/vmime/security/cert/certificateExpiredException.hpp index 7560741b..4db0a1e0 100644 --- a/src/vmime/security/cert/certificateExpiredException.hpp +++ b/src/vmime/security/cert/certificateExpiredException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown when the current date and time is after the validity period * specified in the certificate. */ -class VMIME_EXPORT certificateExpiredException : public certificateException -{ +class VMIME_EXPORT certificateExpiredException : public certificateException { + public: /** Constructs a certificateExpiredException with no detail message. diff --git a/src/vmime/security/cert/certificateIssuerVerificationException.cpp b/src/vmime/security/cert/certificateIssuerVerificationException.cpp index 1e57b6d2..adf50490 100644 --- a/src/vmime/security/cert/certificateIssuerVerificationException.cpp +++ b/src/vmime/security/cert/certificateIssuerVerificationException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,13 +36,13 @@ namespace cert { certificateIssuerVerificationException::certificateIssuerVerificationException() - : certificateException("Certificate subject/issuer verification failed.") -{ + : certificateException("Certificate subject/issuer verification failed.") { + } -exception* certificateIssuerVerificationException::clone() const -{ +exception* certificateIssuerVerificationException::clone() const { + return new certificateIssuerVerificationException(); } diff --git a/src/vmime/security/cert/certificateIssuerVerificationException.hpp b/src/vmime/security/cert/certificateIssuerVerificationException.hpp index 3d3f9a1d..e22bd924 100644 --- a/src/vmime/security/cert/certificateIssuerVerificationException.hpp +++ b/src/vmime/security/cert/certificateIssuerVerificationException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown when a certificate in a certificate chain cannot be verified * against the next certificate in the chain (the issuer). */ -class VMIME_EXPORT certificateIssuerVerificationException : public certificateException -{ +class VMIME_EXPORT certificateIssuerVerificationException : public certificateException { + public: /** Constructs a certificateIssuerVerificationException with no detail message. diff --git a/src/vmime/security/cert/certificateNotTrustedException.cpp b/src/vmime/security/cert/certificateNotTrustedException.cpp index 12b932e6..a5ebb993 100644 --- a/src/vmime/security/cert/certificateNotTrustedException.cpp +++ b/src/vmime/security/cert/certificateNotTrustedException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,13 +36,13 @@ namespace cert { certificateNotTrustedException::certificateNotTrustedException() - : certificateException("Cannot verify certificate against trusted certificates.") -{ + : certificateException("Cannot verify certificate against trusted certificates.") { + } -exception* certificateNotTrustedException::clone() const -{ +exception* certificateNotTrustedException::clone() const { + return new certificateNotTrustedException(); } diff --git a/src/vmime/security/cert/certificateNotTrustedException.hpp b/src/vmime/security/cert/certificateNotTrustedException.hpp index 35881cc3..8cdb2f04 100644 --- a/src/vmime/security/cert/certificateNotTrustedException.hpp +++ b/src/vmime/security/cert/certificateNotTrustedException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown when a certificate cannot be verified against root and/or * trusted certificates. */ -class VMIME_EXPORT certificateNotTrustedException : public certificateException -{ +class VMIME_EXPORT certificateNotTrustedException : public certificateException { + public: /** Constructs a certificateNotTrustedException with no detail message. diff --git a/src/vmime/security/cert/certificateNotYetValidException.cpp b/src/vmime/security/cert/certificateNotYetValidException.cpp index da712b35..ed8ca79e 100644 --- a/src/vmime/security/cert/certificateNotYetValidException.cpp +++ b/src/vmime/security/cert/certificateNotYetValidException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,13 +36,13 @@ namespace cert { certificateNotYetValidException::certificateNotYetValidException() - : certificateException("The certificate is not yet valid.") -{ + : certificateException("The certificate is not yet valid.") { + } -exception* certificateNotYetValidException::clone() const -{ +exception* certificateNotYetValidException::clone() const { + return new certificateNotYetValidException(); } diff --git a/src/vmime/security/cert/certificateNotYetValidException.hpp b/src/vmime/security/cert/certificateNotYetValidException.hpp index e412f466..8f321eb2 100644 --- a/src/vmime/security/cert/certificateNotYetValidException.hpp +++ b/src/vmime/security/cert/certificateNotYetValidException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown when the current date and time is before the validity period * specified in the certificate. */ -class VMIME_EXPORT certificateNotYetValidException : public certificateException -{ +class VMIME_EXPORT certificateNotYetValidException : public certificateException { + public: /** Constructs a certificateNotYetValidException with no detail message. diff --git a/src/vmime/security/cert/certificateVerifier.hpp b/src/vmime/security/cert/certificateVerifier.hpp index eb6ff5eb..7e2913ad 100644 --- a/src/vmime/security/cert/certificateVerifier.hpp +++ b/src/vmime/security/cert/certificateVerifier.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace cert { /** Verify that a certificate path issued by a server can be trusted. */ -class VMIME_EXPORT certificateVerifier : public object -{ +class VMIME_EXPORT certificateVerifier : public object { + public: /** Verify that the specified certificate chain is trusted. diff --git a/src/vmime/security/cert/defaultCertificateVerifier.cpp b/src/vmime/security/cert/defaultCertificateVerifier.cpp index 39391231..33162a0a 100644 --- a/src/vmime/security/cert/defaultCertificateVerifier.cpp +++ b/src/vmime/security/cert/defaultCertificateVerifier.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,55 +39,61 @@ namespace security { namespace cert { -defaultCertificateVerifier::defaultCertificateVerifier() -{ +defaultCertificateVerifier::defaultCertificateVerifier() { + } -defaultCertificateVerifier::~defaultCertificateVerifier() -{ +defaultCertificateVerifier::~defaultCertificateVerifier() { + } defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateVerifier&) - : certificateVerifier() -{ + : certificateVerifier() { + // Not used } -void defaultCertificateVerifier::verify - (const shared_ptr & chain, const string& hostname) -{ - if (chain->getCount() == 0) +void defaultCertificateVerifier::verify( + const shared_ptr & chain, + const string& hostname +) { + + if (chain->getCount() == 0) { return; + } const string type = chain->getAt(0)->getType(); - if (type == "X.509") + if (type == "X.509") { verifyX509(chain, hostname); - else + } else { throw unsupportedCertificateTypeException(type); + } } -void defaultCertificateVerifier::verifyX509 - (const shared_ptr & chain, const string& hostname) -{ +void defaultCertificateVerifier::verifyX509( + const shared_ptr & chain, + const string& hostname +) { + // For every certificate in the chain, verify that the certificate // has been issued by the next certificate in the chain - if (chain->getCount() >= 2) - { - for (size_t i = 0 ; i < chain->getCount() - 1 ; ++i) - { + if (chain->getCount() >= 2) { + + for (size_t i = 0 ; i < chain->getCount() - 1 ; ++i) { + shared_ptr cert = dynamicCast (chain->getAt(i)); shared_ptr next = dynamicCast (chain->getAt(i + 1)); - if (!cert->checkIssuer(next)) - { + if (!cert->checkIssuer(next)) { + certificateIssuerVerificationException ex; ex.setCertificate(cert); @@ -98,8 +104,8 @@ void defaultCertificateVerifier::verifyX509 // For every certificate in the chain, verify that the certificate // is valid at the current time - for (size_t i = 0 ; i < chain->getCount() ; ++i) - { + for (size_t i = 0 ; i < chain->getCount() ; ++i) { + shared_ptr cert = dynamicCast (chain->getAt(i)); @@ -115,12 +121,13 @@ void defaultCertificateVerifier::verifyX509 bool trusted = false; - for (size_t i = 0 ; !trusted && i < m_x509RootCAs.size() ; ++i) - { + for (size_t i = 0 ; !trusted && i < m_x509RootCAs.size() ; ++i) { + shared_ptr rootCa = m_x509RootCAs[i]; - if (lastCert->verify(rootCa)) + if (lastCert->verify(rootCa)) { trusted = true; + } } // -- Next, if the issuer certificate cannot be verified against @@ -129,16 +136,17 @@ void defaultCertificateVerifier::verifyX509 shared_ptr firstCert = dynamicCast (chain->getAt(0)); - for (size_t i = 0 ; !trusted && i < m_x509TrustedCerts.size() ; ++i) - { + for (size_t i = 0 ; !trusted && i < m_x509TrustedCerts.size() ; ++i) { + shared_ptr cert = m_x509TrustedCerts[i]; - if (firstCert->equals(cert)) + if (firstCert->equals(cert)) { trusted = true; + } } - if (!trusted) - { + if (!trusted) { + certificateNotTrustedException ex; ex.setCertificate(firstCert); @@ -146,8 +154,8 @@ void defaultCertificateVerifier::verifyX509 } // Ensure the first certificate's subject name matches server hostname - if (!firstCert->verifyHostName(hostname)) - { + if (!firstCert->verifyHostName(hostname)) { + serverIdentityException ex; ex.setCertificate(firstCert); @@ -156,16 +164,18 @@ void defaultCertificateVerifier::verifyX509 } -void defaultCertificateVerifier::setX509RootCAs - (const std::vector >& caCerts) -{ +void defaultCertificateVerifier::setX509RootCAs( + const std::vector >& caCerts +) { + m_x509RootCAs = caCerts; } -void defaultCertificateVerifier::setX509TrustedCerts - (const std::vector >& trustedCerts) -{ +void defaultCertificateVerifier::setX509TrustedCerts( + const std::vector >& trustedCerts +) { + m_x509TrustedCerts = trustedCerts; } diff --git a/src/vmime/security/cert/defaultCertificateVerifier.hpp b/src/vmime/security/cert/defaultCertificateVerifier.hpp index cd57c5c1..4aa4445c 100644 --- a/src/vmime/security/cert/defaultCertificateVerifier.hpp +++ b/src/vmime/security/cert/defaultCertificateVerifier.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ class X509Certificate; /** Default implementation for certificate verification. */ -class VMIME_EXPORT defaultCertificateVerifier : public certificateVerifier -{ +class VMIME_EXPORT defaultCertificateVerifier : public certificateVerifier { + private: defaultCertificateVerifier(const defaultCertificateVerifier&); diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp index e23abc6d..3dfa1c6f 100644 --- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,15 +44,15 @@ namespace cert { #ifndef VMIME_BUILDING_DOC -struct GnuTLSX509CertificateInternalData -{ - GnuTLSX509CertificateInternalData() - { +struct GnuTLSX509CertificateInternalData { + + GnuTLSX509CertificateInternalData() { + gnutls_x509_crt_init(&cert); } - ~GnuTLSX509CertificateInternalData() - { + ~GnuTLSX509CertificateInternalData() { + gnutls_x509_crt_deinit(cert); } @@ -69,38 +69,39 @@ struct GnuTLSX509CertificateInternalData X509Certificate_GnuTLS::X509Certificate_GnuTLS() - : m_data(new GnuTLSX509CertificateInternalData) -{ + : m_data(new GnuTLSX509CertificateInternalData) { + } X509Certificate_GnuTLS::X509Certificate_GnuTLS(const X509Certificate&) - : X509Certificate(), m_data(NULL) -{ + : X509Certificate(), m_data(NULL) { + // Not used } -X509Certificate_GnuTLS::~X509Certificate_GnuTLS() -{ +X509Certificate_GnuTLS::~X509Certificate_GnuTLS() { + delete m_data; } -void* X509Certificate_GnuTLS::getInternalData() -{ +void* X509Certificate_GnuTLS::getInternalData() { + return &m_data->cert; } // static -shared_ptr X509Certificate::import(utility::inputStream& is) -{ +shared_ptr X509Certificate::import( + utility::inputStream& is +) { + byteArray bytes; byte_t chunk[4096]; - while (!is.eof()) - { + while (!is.eof()) { const size_t len = is.read(chunk, sizeof(chunk)); bytes.insert(bytes.end(), chunk, chunk + len); } @@ -110,9 +111,11 @@ shared_ptr X509Certificate::import(utility::inputStream& is) // static -shared_ptr X509Certificate::import - (const byte_t* data, const size_t length) -{ +shared_ptr X509Certificate::import( + const byte_t* data, + const size_t length +) { + gnutls_datum_t buffer; buffer.data = const_cast (data); buffer.size = static_cast (length); @@ -120,28 +123,31 @@ shared_ptr X509Certificate::import // Try DER format shared_ptr derCert = make_shared (); - if (gnutls_x509_crt_import(derCert->m_data->cert, &buffer, GNUTLS_X509_FMT_DER) >= 0) + if (gnutls_x509_crt_import(derCert->m_data->cert, &buffer, GNUTLS_X509_FMT_DER) >= 0) { return derCert; + } // Try PEM format shared_ptr pemCert = make_shared (); - if (gnutls_x509_crt_import(pemCert->m_data->cert, &buffer, GNUTLS_X509_FMT_PEM) >= 0) + if (gnutls_x509_crt_import(pemCert->m_data->cert, &buffer, GNUTLS_X509_FMT_PEM) >= 0) { return pemCert; + } return null; } // static -void X509Certificate::import(utility::inputStream& is, - std::vector >& certs) -{ +void X509Certificate::import( + utility::inputStream& is, + std::vector >& certs +) { + byteArray bytes; byte_t chunk[4096]; - while (!is.eof()) - { + while (!is.eof()) { const size_t len = is.read(chunk, sizeof(chunk)); bytes.insert(bytes.end(), chunk, chunk + len); } @@ -151,9 +157,12 @@ void X509Certificate::import(utility::inputStream& is, // static -void X509Certificate::import(const byte_t* data, const size_t length, - std::vector >& certs) -{ +void X509Certificate::import( + const byte_t* data, + const size_t length, + std::vector >& certs +) { + gnutls_datum_t buffer; buffer.data = const_cast (data); buffer.size = static_cast (length); @@ -162,13 +171,16 @@ void X509Certificate::import(const byte_t* data, const size_t length, gnutls_x509_crt_t x509[1024]; // Try DER format - if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_DER, 0) < 0) + if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_DER, 0) < 0) { // Try PEM format - if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_PEM, 0) < 0) + if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_PEM, 0) < 0) { return; + } + } + + for (unsigned int i = 0 ; i < size ; i += 1) { - for (unsigned int i = 0; i < size; i += 1) { auto c = make_shared (); c->m_data->swap(x509[i]); certs.push_back(c); @@ -176,16 +188,17 @@ void X509Certificate::import(const byte_t* data, const size_t length, } -void X509Certificate_GnuTLS::write - (utility::outputStream& os, const Format format) const -{ +void X509Certificate_GnuTLS::write( + utility::outputStream& os, + const Format format +) const { + size_t dataSize = 0; gnutls_x509_crt_fmt_t fmt = GNUTLS_X509_FMT_DER; - switch (format) - { - case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break; - case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break; + switch (format) { + case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break; + case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break; } gnutls_x509_crt_export(m_data->cert, fmt, NULL, &dataSize); @@ -198,8 +211,8 @@ void X509Certificate_GnuTLS::write } -const byteArray X509Certificate_GnuTLS::getSerialNumber() const -{ +const byteArray X509Certificate_GnuTLS::getSerialNumber() const { + char serial[64]; size_t serialSize = sizeof(serial); @@ -209,40 +222,43 @@ const byteArray X509Certificate_GnuTLS::getSerialNumber() const } -bool X509Certificate_GnuTLS::checkIssuer(const shared_ptr & issuer_) const -{ +bool X509Certificate_GnuTLS::checkIssuer(const shared_ptr & issuer_) const { + shared_ptr issuer = dynamicCast (issuer_); - return (gnutls_x509_crt_check_issuer - (m_data->cert, issuer->m_data->cert) >= 1); + return gnutls_x509_crt_check_issuer(m_data->cert, issuer->m_data->cert) >= 1; } -bool X509Certificate_GnuTLS::verify(const shared_ptr & caCert_) const -{ +bool X509Certificate_GnuTLS::verify(const shared_ptr & caCert_) const { + shared_ptr caCert = dynamicCast (caCert_); unsigned int verify = 0; - const int res = gnutls_x509_crt_verify - (m_data->cert, &(caCert->m_data->cert), 1, - GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, - &verify); + const int res = gnutls_x509_crt_verify( + m_data->cert, &(caCert->m_data->cert), 1, + GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, + &verify + ); - return (res == 0 && verify == 0); + return res == 0 && verify == 0; } -bool X509Certificate_GnuTLS::verifyHostName - (const string& hostname, std::vector * nonMatchingNames) const -{ - if (gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0) - return true; +bool X509Certificate_GnuTLS::verifyHostName( + const string& hostname, + std::vector * nonMatchingNames +) const { + + if (gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0) { + return true; + } + + if (nonMatchingNames) { - if (nonMatchingNames) - { const int MAX_CN = 256; const char* OID_X520_COMMON_NAME = "2.5.4.3"; @@ -251,16 +267,18 @@ bool X509Certificate_GnuTLS::verifyHostName dnsNameLength = sizeof(dnsName); - if (gnutls_x509_crt_get_dn_by_oid(m_data->cert, OID_X520_COMMON_NAME, 0, 0, dnsName, &dnsNameLength) >= 0) + if (gnutls_x509_crt_get_dn_by_oid(m_data->cert, OID_X520_COMMON_NAME, 0, 0, dnsName, &dnsNameLength) >= 0) { nonMatchingNames->push_back(dnsName); + } + + for (int i = 0, ret = 0 ; ret >= 0 ; ++i) { - for (int i = 0, ret = 0 ; ret >= 0 ; ++i) - { dnsNameLength = sizeof(dnsName); ret = gnutls_x509_crt_get_subject_alt_name(m_data->cert, i, dnsName, &dnsNameLength, NULL); - if (ret == GNUTLS_SAN_DNSNAME) + if (ret == GNUTLS_SAN_DNSNAME) { nonMatchingNames->push_back(dnsName); + } } } @@ -268,47 +286,45 @@ bool X509Certificate_GnuTLS::verifyHostName } -const datetime X509Certificate_GnuTLS::getActivationDate() const -{ +const datetime X509Certificate_GnuTLS::getActivationDate() const { + const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert); return datetime(t); } -const datetime X509Certificate_GnuTLS::getExpirationDate() const -{ +const datetime X509Certificate_GnuTLS::getExpirationDate() const { + const time_t t = gnutls_x509_crt_get_expiration_time(m_data->cert); return datetime(t); } -const byteArray X509Certificate_GnuTLS::getFingerprint(const DigestAlgorithm algo) const -{ +const byteArray X509Certificate_GnuTLS::getFingerprint(const DigestAlgorithm algo) const { + gnutls_digest_algorithm_t galgo; - switch (algo) - { - case DIGEST_MD5: + switch (algo) { - galgo = GNUTLS_DIG_MD5; - break; + case DIGEST_MD5: - default: - case DIGEST_SHA1: + galgo = GNUTLS_DIG_MD5; + break; - galgo = GNUTLS_DIG_SHA; - break; + default: + case DIGEST_SHA1: + + galgo = GNUTLS_DIG_SHA; + break; } size_t bufferSize = 0; - gnutls_x509_crt_get_fingerprint - (m_data->cert, galgo, NULL, &bufferSize); + gnutls_x509_crt_get_fingerprint(m_data->cert, galgo, NULL, &bufferSize); std::vector buffer(bufferSize); - if (gnutls_x509_crt_get_fingerprint - (m_data->cert, galgo, &buffer[0], &bufferSize) == 0) - { + if (gnutls_x509_crt_get_fingerprint(m_data->cert, galgo, &buffer[0], &bufferSize) == 0) { + byteArray res; res.insert(res.end(), &buffer[0], &buffer[0] + bufferSize); @@ -319,8 +335,8 @@ const byteArray X509Certificate_GnuTLS::getFingerprint(const DigestAlgorithm alg } -const byteArray X509Certificate_GnuTLS::getEncoded() const -{ +const byteArray X509Certificate_GnuTLS::getEncoded() const { + byteArray bytes; utility::outputStreamByteArrayAdapter os(bytes); @@ -330,37 +346,39 @@ const byteArray X509Certificate_GnuTLS::getEncoded() const } -const string X509Certificate_GnuTLS::getIssuerString() const -{ +const string X509Certificate_GnuTLS::getIssuerString() const { + char buffer[4096]; size_t bufferSize = sizeof(buffer); - if (gnutls_x509_crt_get_issuer_dn(m_data->cert, buffer, &bufferSize) != GNUTLS_E_SUCCESS) + if (gnutls_x509_crt_get_issuer_dn(m_data->cert, buffer, &bufferSize) != GNUTLS_E_SUCCESS) { return ""; + } return buffer; } -const string X509Certificate_GnuTLS::getType() const -{ +const string X509Certificate_GnuTLS::getType() const { + return "X.509"; } -int X509Certificate_GnuTLS::getVersion() const -{ +int X509Certificate_GnuTLS::getVersion() const { + return gnutls_x509_crt_get_version(m_data->cert); } -bool X509Certificate_GnuTLS::equals(const shared_ptr & other) const -{ +bool X509Certificate_GnuTLS::equals(const shared_ptr & other) const { + shared_ptr otherX509 = dynamicCast (other); - if (!otherX509) + if (!otherX509) { return false; + } const byteArray fp1 = getFingerprint(DIGEST_MD5); const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5); diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp index f06955bf..c7c6c482 100644 --- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,8 +39,8 @@ namespace security { namespace cert { -class X509Certificate_GnuTLS : public X509Certificate -{ +class X509Certificate_GnuTLS : public X509Certificate { + friend class X509Certificate; X509Certificate_GnuTLS(const X509Certificate&); @@ -61,9 +61,10 @@ public: bool verify(const shared_ptr & caCert) const; - bool verifyHostName - (const string& hostname, - std::vector * nonMatchingNames = NULL) const; + bool verifyHostName( + const string& hostname, + std::vector * nonMatchingNames = NULL + ) const; const datetime getExpirationDate() const; const datetime getActivationDate() const; diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp index 9ce09592..268a42c2 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -65,12 +65,12 @@ static net::tls::OpenSSLInitializer::autoInitializer openSSLInitializer; #ifndef VMIME_BUILDING_DOC -class monthMap -{ +class monthMap { + public: - monthMap() - { + monthMap() { + m_monthMap["jan"] = vmime::datetime::JAN; m_monthMap["feb"] = vmime::datetime::FEB; m_monthMap["mar"] = vmime::datetime::MAR; @@ -85,15 +85,16 @@ public: m_monthMap["dec"] = vmime::datetime::DEC; } - int getMonth(vmime::string mstr) - { + int getMonth(vmime::string mstr) { + std::transform(mstr.begin(), mstr.end(), mstr.begin(), ::tolower); std::map ::const_iterator c_it = m_monthMap.find(mstr); - if (c_it != m_monthMap.end()) + if (c_it != m_monthMap.end()) { return c_it->second; + } return -1; } @@ -107,17 +108,18 @@ static monthMap sg_monthMap; -struct OpenSSLX509CertificateInternalData -{ - OpenSSLX509CertificateInternalData() - { +struct OpenSSLX509CertificateInternalData { + + OpenSSLX509CertificateInternalData() { + cert = 0; } - ~OpenSSLX509CertificateInternalData() - { - if (cert) + ~OpenSSLX509CertificateInternalData() { + + if (cert) { X509_free(cert); + } } X509* cert; @@ -125,14 +127,14 @@ struct OpenSSLX509CertificateInternalData // Workaround for i2v() taking either a const or a non-const 'method' on some platforms -STACK_OF(CONF_VALUE)* call_i2v(const X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) -{ +STACK_OF(CONF_VALUE)* call_i2v(const X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) { + return m->i2v(m, p1, p2); } -STACK_OF(CONF_VALUE)* call_i2v(X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) -{ +STACK_OF(CONF_VALUE)* call_i2v(X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) { + return m->i2v(m, p1, p2); } @@ -141,55 +143,55 @@ STACK_OF(CONF_VALUE)* call_i2v(X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VAL X509Certificate_OpenSSL::X509Certificate_OpenSSL() - : m_data(new OpenSSLX509CertificateInternalData) -{ + : m_data(new OpenSSLX509CertificateInternalData) { + } X509Certificate_OpenSSL::X509Certificate_OpenSSL(X509* cert) - : m_data(new OpenSSLX509CertificateInternalData) -{ + : m_data(new OpenSSLX509CertificateInternalData) { + m_data->cert = X509_dup(cert); } X509Certificate_OpenSSL::X509Certificate_OpenSSL(const X509Certificate_OpenSSL&) - : X509Certificate(), m_data(NULL) -{ + : X509Certificate(), m_data(NULL) { + // Not used } -X509Certificate_OpenSSL::~X509Certificate_OpenSSL() -{ +X509Certificate_OpenSSL::~X509Certificate_OpenSSL() { + delete m_data; } -void* X509Certificate_OpenSSL::getInternalData() -{ +void* X509Certificate_OpenSSL::getInternalData() { + return &m_data->cert; } // static -shared_ptr X509Certificate_OpenSSL::importInternal(X509* cert) -{ - if (cert) +shared_ptr X509Certificate_OpenSSL::importInternal(X509* cert) { + + if (cert) { return make_shared (reinterpret_cast (cert)); + } return null; } // static -shared_ptr X509Certificate::import(utility::inputStream& is) -{ +shared_ptr X509Certificate::import(utility::inputStream& is) { + byteArray bytes; byte_t chunk[4096]; - while (!is.eof()) - { + while (!is.eof()) { const size_t len = is.read(chunk, sizeof(chunk)); bytes.insert(bytes.end(), chunk, chunk + len); } @@ -199,15 +201,16 @@ shared_ptr X509Certificate::import(utility::inputStream& is) // static -shared_ptr X509Certificate::import - (const byte_t* data, const size_t length) -{ +shared_ptr X509Certificate::import( + const byte_t* data, + const size_t length +) { + shared_ptr cert = make_shared (); BIO* membio = BIO_new_mem_buf(const_cast (data), static_cast (length)); - if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) - { + if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) { BIO_vfree(membio); return null; } @@ -219,14 +222,15 @@ shared_ptr X509Certificate::import // static -void X509Certificate::import(utility::inputStream& is, - std::vector >& certs) -{ +void X509Certificate::import( + utility::inputStream& is, + std::vector >& certs +) { + byteArray bytes; byte_t chunk[4096]; - while (!is.eof()) - { + while (!is.eof()) { const size_t len = is.read(chunk, sizeof(chunk)); bytes.insert(bytes.end(), chunk, chunk + len); } @@ -236,16 +240,23 @@ void X509Certificate::import(utility::inputStream& is, // static -void X509Certificate::import(const byte_t* data, const size_t length, - std::vector >& certs) -{ +void X509Certificate::import( + const byte_t* data, + const size_t length, + std::vector >& certs +) { BIO* membio = BIO_new_mem_buf(const_cast (data), static_cast (length)); shared_ptr cert = null; while (true) { + cert = make_shared (); - if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) break; + + if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) { + break; + } + certs.push_back(cert); } @@ -253,37 +264,41 @@ void X509Certificate::import(const byte_t* data, const size_t length, } -void X509Certificate_OpenSSL::write - (utility::outputStream& os, const Format format) const -{ +void X509Certificate_OpenSSL::write( + utility::outputStream& os, + const Format format +) const { + BIO* membio = 0; long dataSize = 0; unsigned char* out = 0; - if (format == FORMAT_DER) - { - if ((dataSize = i2d_X509(m_data->cert, &out)) < 0) + if (format == FORMAT_DER) { + + if ((dataSize = i2d_X509(m_data->cert, &out)) < 0) { goto err; + } os.write(reinterpret_cast (out), dataSize); os.flush(); OPENSSL_free(out); - } - else if (format == FORMAT_PEM) - { + + } else if (format == FORMAT_PEM) { + membio = BIO_new(BIO_s_mem()); BIO_set_close(membio, BIO_CLOSE); - if (!PEM_write_bio_X509(membio, m_data->cert)) + if (!PEM_write_bio_X509(membio, m_data->cert)) { goto pem_err; + } dataSize = BIO_get_mem_data(membio, &out); os.write(reinterpret_cast (out), dataSize); os.flush(); BIO_vfree(membio); - } - else - { + + } else { + throw unsupportedCertificateTypeException("Unknown format"); } @@ -291,8 +306,9 @@ void X509Certificate_OpenSSL::write pem_err: { - if (membio) + if (membio) { BIO_vfree(membio); + } } err: @@ -300,14 +316,13 @@ err: char errstr[256]; long ec = ERR_get_error(); ERR_error_string(ec, errstr); - throw certificateException( - "OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr)); + throw certificateException("OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr)); } } -const byteArray X509Certificate_OpenSSL::getSerialNumber() const -{ +const byteArray X509Certificate_OpenSSL::getSerialNumber() const { + ASN1_INTEGER *serial = X509_get_serialNumber(m_data->cert); BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL); int n = BN_num_bytes(bnser); @@ -320,8 +335,8 @@ const byteArray X509Certificate_OpenSSL::getSerialNumber() const } -bool X509Certificate_OpenSSL::checkIssuer(const shared_ptr & cert_) const -{ +bool X509Certificate_OpenSSL::checkIssuer(const shared_ptr & cert_) const { + shared_ptr cert = dynamicCast (cert_); @@ -347,8 +362,8 @@ bool X509Certificate_OpenSSL::checkIssuer(const shared_ptr & caCert_) const -{ +bool X509Certificate_OpenSSL::verify(const shared_ptr & caCert_) const { + shared_ptr caCert = dynamicCast (caCert_); @@ -358,25 +373,25 @@ bool X509Certificate_OpenSSL::verify(const shared_ptr & c X509_STORE *store = X509_STORE_new(); - if (store) - { + if (store) { + X509_STORE_CTX *verifyCtx = X509_STORE_CTX_new(); - if (verifyCtx) - { - if (X509_STORE_add_cert(store, caCert->m_data->cert)) - { + if (verifyCtx) { + + if (X509_STORE_add_cert(store, caCert->m_data->cert)) { + X509_STORE_CTX_init(verifyCtx, store, m_data->cert, NULL); int ret = X509_verify_cert(verifyCtx); - if (ret == 1) - { + if (ret == 1) { + verified = true; error = false; - } - else if (ret == 0) - { + + } else if (ret == 0) { + verified = false; error = false; } @@ -395,8 +410,8 @@ bool X509Certificate_OpenSSL::verify(const shared_ptr & c // static -bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host) -{ +bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host) { + // Right-to-left match, looking for a '*' wildcard const bool hasWildcard = (strlen(cnBuf) > 1 && cnBuf[0] == '*' && cnBuf[1] == '.'); const char* cnBufReverseEndPtr = (cnBuf + (hasWildcard ? 2 : 0)); @@ -405,29 +420,34 @@ bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host) bool matches = true; - while (matches && --hostPtr >= host && --cnPtr >= cnBufReverseEndPtr) + while (matches && --hostPtr >= host && --cnPtr >= cnBufReverseEndPtr) { matches = (toupper(*hostPtr) == toupper(*cnPtr)); + } return matches; } -bool X509Certificate_OpenSSL::verifyHostName - (const string& hostname, std::vector * nonMatchingNames) const -{ +bool X509Certificate_OpenSSL::verifyHostName( + const string& hostname, + std::vector * nonMatchingNames +) const { + // First, check subject common name against hostname char CNBuffer[1024]; CNBuffer[sizeof(CNBuffer) - 1] = '\0'; X509_NAME* xname = X509_get_subject_name(m_data->cert); - if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1) - { - if (cnMatch(CNBuffer, hostname.c_str())) - return true; + if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1) { - if (nonMatchingNames) + if (cnMatch(CNBuffer, hostname.c_str())) { + return true; + } + + if (nonMatchingNames) { nonMatchingNames->push_back(CNBuffer); + } } // Now, look in subject alternative names @@ -436,34 +456,34 @@ bool X509Certificate_OpenSSL::verifyHostName STACK_OF(GENERAL_NAME)* altNames = static_cast (X509_get_ext_d2i(m_data->cert, NID_subject_alt_name, NULL, NULL)); - if (altNames == NULL) + if (altNames == NULL) { return false; + } // Check each name within the extension - for (int i = 0, n = sk_GENERAL_NAME_num(altNames) ; i < n ; ++i) - { + for (int i = 0, n = sk_GENERAL_NAME_num(altNames) ; i < n ; ++i) { + const GENERAL_NAME* currentName = sk_GENERAL_NAME_value(altNames, i); - if (currentName->type == GEN_DNS) - { + if (currentName->type == GEN_DNS) { + // Current name is a DNS name, let's check it char *DNSName = (char *) ASN1_STRING_data(currentName->d.dNSName); // Make sure there isn't an embedded NUL character in the DNS name - if (ASN1_STRING_length(currentName->d.dNSName) != strlen(DNSName)) - { + if (ASN1_STRING_length(currentName->d.dNSName) != strlen(DNSName)) { // Malformed certificate break; } - if (cnMatch(DNSName, hostname.c_str())) - { + if (cnMatch(DNSName, hostname.c_str())) { verify = true; break; } - if (nonMatchingNames) + if (nonMatchingNames) { nonMatchingNames->push_back(DNSName); + } } } @@ -473,8 +493,8 @@ bool X509Certificate_OpenSSL::verifyHostName } -const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const -{ +const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const { + char* buffer; BIO* out = BIO_new(BIO_s_mem()); BIO_set_close(out, BIO_CLOSE); @@ -491,15 +511,16 @@ const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const BIO_free(out); delete [] dest; - if (t.size() > 0) - { + if (t.size() > 0) { + char month[4] = {0}; char zone[4] = {0}; int day, hour, minute, second, year; int nrconv = sscanf(t.c_str(), "%s %2d %02d:%02d:%02d %d%s", month, &day, &hour, &minute, &second,&year,zone); - if (nrconv >= 6) + if (nrconv >= 6) { return datetime(year, sg_monthMap.getMonth(vmime::string(month)), day, hour, minute, second); + } } // let datetime try and parse it @@ -507,20 +528,20 @@ const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const } -const datetime X509Certificate_OpenSSL::getActivationDate() const -{ +const datetime X509Certificate_OpenSSL::getActivationDate() const { + return convertX509Date(X509_get_notBefore(m_data->cert)); } -const datetime X509Certificate_OpenSSL::getExpirationDate() const -{ +const datetime X509Certificate_OpenSSL::getExpirationDate() const { + return convertX509Date(X509_get_notAfter(m_data->cert)); } -const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm algo) const -{ +const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm algo) const { + BIO *out; int j; unsigned int n; @@ -528,29 +549,28 @@ const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm al unsigned char * fingerprint; unsigned char md[EVP_MAX_MD_SIZE]; - switch (algo) - { - case DIGEST_MD5: + switch (algo) { - digest = EVP_md5(); - break; + case DIGEST_MD5: - default: - case DIGEST_SHA1: + digest = EVP_md5(); + break; - digest = EVP_sha1(); - break; + default: + case DIGEST_SHA1: + + digest = EVP_sha1(); + break; } out = BIO_new(BIO_s_mem()); BIO_set_close(out, BIO_CLOSE); - if (X509_digest(m_data->cert, digest, md, &n)) - { - for (j=0; j<(int)n; j++) - { - BIO_printf (out, "%02X",md[j]); - if (j+1 != (int)n) BIO_printf(out, ":"); + if (X509_digest(m_data->cert, digest, md, &n)) { + + for (j = 0 ; j < (int) n ; j++) { + BIO_printf(out, "%02X", md[j]); + if (j + 1 != (int) n) BIO_printf(out, ":"); } } @@ -568,8 +588,8 @@ const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm al } -const byteArray X509Certificate_OpenSSL::getEncoded() const -{ +const byteArray X509Certificate_OpenSSL::getEncoded() const { + byteArray bytes; utility::outputStreamByteArrayAdapter os(bytes); @@ -579,8 +599,8 @@ const byteArray X509Certificate_OpenSSL::getEncoded() const } -const string X509Certificate_OpenSSL::getIssuerString() const -{ +const string X509Certificate_OpenSSL::getIssuerString() const { + // Get issuer for this cert BIO* out = BIO_new(BIO_s_mem()); X509_NAME_print_ex(out, X509_get_issuer_name(m_data->cert), 0, XN_FLAG_RFC2253); @@ -595,25 +615,26 @@ const string X509Certificate_OpenSSL::getIssuerString() const } -const string X509Certificate_OpenSSL::getType() const -{ +const string X509Certificate_OpenSSL::getType() const { + return "X.509"; } -int X509Certificate_OpenSSL::getVersion() const -{ - return (int)X509_get_version(m_data->cert); +int X509Certificate_OpenSSL::getVersion() const { + + return (int) X509_get_version(m_data->cert); } -bool X509Certificate_OpenSSL::equals(const shared_ptr & other) const -{ +bool X509Certificate_OpenSSL::equals(const shared_ptr & other) const { + shared_ptr otherX509 = dynamicCast (other); - if (!otherX509) + if (!otherX509) { return false; + } const byteArray fp1 = getFingerprint(DIGEST_MD5); const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5); diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp index 89b54a9a..c0ebf3c3 100644 --- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ namespace security { namespace cert { -class X509Certificate_OpenSSL : public X509Certificate -{ +class X509Certificate_OpenSSL : public X509Certificate { + friend class X509Certificate; X509Certificate_OpenSSL(const X509Certificate_OpenSSL&); @@ -64,9 +64,10 @@ public: bool verify(const shared_ptr & caCert) const; - bool verifyHostName - (const string& hostname, - std::vector * nonMatchingNames = NULL) const; + bool verifyHostName( + const string& hostname, + std::vector * nonMatchingNames = NULL + ) const; const datetime getExpirationDate() const; const datetime getActivationDate() const; diff --git a/src/vmime/security/cert/serverIdentityException.cpp b/src/vmime/security/cert/serverIdentityException.cpp index 585d1021..fcbe571f 100644 --- a/src/vmime/security/cert/serverIdentityException.cpp +++ b/src/vmime/security/cert/serverIdentityException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,13 +36,13 @@ namespace cert { serverIdentityException::serverIdentityException() - : certificateException("Server identity cannot be verified.") -{ + : certificateException("Server identity cannot be verified.") { + } -exception* serverIdentityException::clone() const -{ +exception* serverIdentityException::clone() const { + return new serverIdentityException(); } diff --git a/src/vmime/security/cert/serverIdentityException.hpp b/src/vmime/security/cert/serverIdentityException.hpp index 47feced7..358553ed 100644 --- a/src/vmime/security/cert/serverIdentityException.hpp +++ b/src/vmime/security/cert/serverIdentityException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ namespace cert { /** Thrown when the subject name of a certificate does not match * the hostname of the server. */ -class VMIME_EXPORT serverIdentityException : public certificateException -{ +class VMIME_EXPORT serverIdentityException : public certificateException { + public: /** Constructs a serverIdentityException with no detail message. diff --git a/src/vmime/security/cert/unsupportedCertificateTypeException.cpp b/src/vmime/security/cert/unsupportedCertificateTypeException.cpp index b27bb8be..57656512 100644 --- a/src/vmime/security/cert/unsupportedCertificateTypeException.cpp +++ b/src/vmime/security/cert/unsupportedCertificateTypeException.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,18 +37,18 @@ namespace cert { unsupportedCertificateTypeException::unsupportedCertificateTypeException(const string& type) : certificateException(string("Unsupported certificate type: '") + type + "'."), - m_type(type) -{ + m_type(type) { + } -unsupportedCertificateTypeException::~unsupportedCertificateTypeException() throw() -{ +unsupportedCertificateTypeException::~unsupportedCertificateTypeException() throw() { + } -exception* unsupportedCertificateTypeException::clone() const -{ +exception* unsupportedCertificateTypeException::clone() const { + return new unsupportedCertificateTypeException(m_type); } diff --git a/src/vmime/security/cert/unsupportedCertificateTypeException.hpp b/src/vmime/security/cert/unsupportedCertificateTypeException.hpp index 356ac32b..725035f7 100644 --- a/src/vmime/security/cert/unsupportedCertificateTypeException.hpp +++ b/src/vmime/security/cert/unsupportedCertificateTypeException.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ namespace cert { /** Thrown when a certificate is of unsupported format. */ -class VMIME_EXPORT unsupportedCertificateTypeException : public certificateException -{ +class VMIME_EXPORT unsupportedCertificateTypeException : public certificateException { + public: /** Constructs a unsupportedCertificateTypeException. diff --git a/src/vmime/security/defaultAuthenticator.cpp b/src/vmime/security/defaultAuthenticator.cpp index 5503de5f..b2b249c6 100644 --- a/src/vmime/security/defaultAuthenticator.cpp +++ b/src/vmime/security/defaultAuthenticator.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,85 +38,88 @@ namespace vmime { namespace security { -defaultAuthenticator::defaultAuthenticator() -{ +defaultAuthenticator::defaultAuthenticator() { + } -defaultAuthenticator::~defaultAuthenticator() -{ +defaultAuthenticator::~defaultAuthenticator() { + } -const string defaultAuthenticator::getUsername() const -{ +const string defaultAuthenticator::getUsername() const { + shared_ptr service = m_service.lock(); const string prefix = service->getInfos().getPropertyPrefix(); const propertySet& props = service->getSession()->getProperties(); - if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_USERNAME.getName())) + if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_USERNAME.getName())) { return props[prefix + net::serviceInfos::property::AUTH_USERNAME.getName()]; + } throw exceptions::no_auth_information(); } -const string defaultAuthenticator::getPassword() const -{ +const string defaultAuthenticator::getPassword() const { + shared_ptr service = m_service.lock(); const string prefix = service->getInfos().getPropertyPrefix(); const propertySet& props = service->getSession()->getProperties(); - if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_PASSWORD.getName())) + if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_PASSWORD.getName())) { return props[prefix + net::serviceInfos::property::AUTH_PASSWORD.getName()]; + } throw exceptions::no_auth_information(); } -const string defaultAuthenticator::getAccessToken() const -{ +const string defaultAuthenticator::getAccessToken() const { + shared_ptr service = m_service.lock(); const string prefix = service->getInfos().getPropertyPrefix(); const propertySet& props = service->getSession()->getProperties(); - if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName())) + if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName())) { return props[prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName()]; + } throw exceptions::no_auth_information(); } -const string defaultAuthenticator::getHostname() const -{ +const string defaultAuthenticator::getHostname() const { + return platform::getHandler()->getHostName(); } -const string defaultAuthenticator::getAnonymousToken() const -{ +const string defaultAuthenticator::getAnonymousToken() const { + return "anonymous@" + platform::getHandler()->getHostName(); } -const string defaultAuthenticator::getServiceName() const -{ +const string defaultAuthenticator::getServiceName() const { + // Information cannot be provided throw exceptions::no_auth_information(); } -void defaultAuthenticator::setService(const shared_ptr & serv) -{ +void defaultAuthenticator::setService(const shared_ptr & serv) { + m_service = serv; } -weak_ptr defaultAuthenticator::getService() const -{ +weak_ptr defaultAuthenticator::getService() const { + return m_service; } @@ -126,4 +129,3 @@ weak_ptr defaultAuthenticator::getService() const #endif // VMIME_HAVE_MESSAGING_FEATURES - diff --git a/src/vmime/security/defaultAuthenticator.hpp b/src/vmime/security/defaultAuthenticator.hpp index d5b4d787..e053f9ef 100644 --- a/src/vmime/security/defaultAuthenticator.hpp +++ b/src/vmime/security/defaultAuthenticator.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ namespace security { /** An authenticator that can provide some basic information by * reading in the messaging session properties. */ -class VMIME_EXPORT defaultAuthenticator : public authenticator -{ +class VMIME_EXPORT defaultAuthenticator : public authenticator { + public: defaultAuthenticator(); @@ -71,4 +71,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES #endif // VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED - diff --git a/src/vmime/security/digest/md5/md5MessageDigest.cpp b/src/vmime/security/digest/md5/md5MessageDigest.cpp index a83f0623..9a07b57b 100644 --- a/src/vmime/security/digest/md5/md5MessageDigest.cpp +++ b/src/vmime/security/digest/md5/md5MessageDigest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -59,20 +59,20 @@ namespace digest { namespace md5 { -md5MessageDigest::md5MessageDigest() -{ +md5MessageDigest::md5MessageDigest() { + init(); } -void md5MessageDigest::reset() -{ +void md5MessageDigest::reset() { + init(); } -void md5MessageDigest::init() -{ +void md5MessageDigest::init() { + m_hash[0] = 0x67452301; m_hash[1] = 0xefcdab89; m_hash[2] = 0x98badcfe; @@ -83,69 +83,68 @@ void md5MessageDigest::init() } -static void copyUint8Array(vmime_uint8* dest, const vmime_uint8* src, size_t count) -{ - for ( ; count >= 4 ; count -= 4, dest += 4, src += 4) - { +static void copyUint8Array(vmime_uint8* dest, const vmime_uint8* src, size_t count) { + + for ( ; count >= 4 ; count -= 4, dest += 4, src += 4) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; } - for ( ; count ; --count, ++dest, ++src) + for ( ; count ; --count, ++dest, ++src) { dest[0] = src[0]; + } } -static inline vmime_uint32 swapUint32(const vmime_uint32 D) -{ +static inline vmime_uint32 swapUint32(const vmime_uint32 D) { + return ((D << 24) | ((D << 8) & 0x00FF0000) | ((D >> 8) & 0x0000FF00) | (D >> 24)); } -static inline void swapUint32Array(vmime_uint32* buf, size_t words) -{ - for ( ; words >= 4 ; words -= 4, buf += 4) - { +static inline void swapUint32Array(vmime_uint32* buf, size_t words) { + + for ( ; words >= 4 ; words -= 4, buf += 4) { buf[0] = swapUint32(buf[0]); buf[1] = swapUint32(buf[1]); buf[2] = swapUint32(buf[2]); buf[3] = swapUint32(buf[3]); } - for ( ; words ; --words, ++buf) + for ( ; words ; --words, ++buf) { buf[0] = swapUint32(buf[0]); + } } -void md5MessageDigest::update(const byte_t b) -{ +void md5MessageDigest::update(const byte_t b) { + update(&b, 1); } -void md5MessageDigest::update(const string& s) -{ +void md5MessageDigest::update(const string& s) { + update(reinterpret_cast (s.data()), s.length()); } -void md5MessageDigest::update(const byte_t* data, const size_t offset, const size_t len) -{ +void md5MessageDigest::update(const byte_t* data, const size_t offset, const size_t len) { + update(data + offset, len); } -void md5MessageDigest::update(const byte_t* data, const size_t length) -{ +void md5MessageDigest::update(const byte_t* data, const size_t length) { + const size_t avail = 64 - (m_byteCount & 0x3f); size_t len = length; m_byteCount += len; - if (avail > len) - { + if (avail > len) { copyUint8Array(m_block.b8 + (64 - avail), data, len); return; } @@ -156,8 +155,8 @@ void md5MessageDigest::update(const byte_t* data, const size_t length) data += avail; len -= avail; - while (len >= 64) - { + while (len >= 64) { + copyUint8Array(m_block.b8, data, 64); transformHelper(); @@ -169,30 +168,33 @@ void md5MessageDigest::update(const byte_t* data, const size_t length) } -void md5MessageDigest::finalize(const string& s) -{ +void md5MessageDigest::finalize(const string& s) { + update(s); finalize(); } -void md5MessageDigest::finalize(const byte_t* buffer, const size_t len) -{ +void md5MessageDigest::finalize(const byte_t* buffer, const size_t len) { + update(buffer, len); finalize(); } -void md5MessageDigest::finalize(const byte_t* buffer, - const size_t offset, const size_t len) -{ +void md5MessageDigest::finalize( + const byte_t* buffer, + const size_t offset, + const size_t len +) { + update(buffer, offset, len); finalize(); } -void md5MessageDigest::finalize() -{ +void md5MessageDigest::finalize() { + const long offset = m_byteCount & 0x3f; vmime_uint8* p = m_block.b8 + offset; @@ -200,8 +202,8 @@ void md5MessageDigest::finalize() *p++ = 0x80; - if (padding < 0) - { + if (padding < 0) { + memset(p, 0x00, padding + 8); transformHelper(); p = m_block.b8; @@ -227,8 +229,8 @@ void md5MessageDigest::finalize() } -void md5MessageDigest::transformHelper() -{ +void md5MessageDigest::transformHelper() { + #if VMIME_BYTE_ORDER_BIG_ENDIAN swapUint32Array(m_block.b32, 64 / 4); #endif @@ -236,8 +238,8 @@ void md5MessageDigest::transformHelper() } -void md5MessageDigest::transform() -{ +void md5MessageDigest::transform() { + const vmime_uint32* const in = m_block.b32; vmime_uint32 a = m_hash[0]; @@ -328,14 +330,14 @@ void md5MessageDigest::transform() } -size_t md5MessageDigest::getDigestLength() const -{ +size_t md5MessageDigest::getDigestLength() const { + return 16; } -const byte_t* md5MessageDigest::getDigest() const -{ +const byte_t* md5MessageDigest::getDigest() const { + return reinterpret_cast (m_hash); } diff --git a/src/vmime/security/digest/md5/md5MessageDigest.hpp b/src/vmime/security/digest/md5/md5MessageDigest.hpp index ef94f5c8..bdb730a7 100644 --- a/src/vmime/security/digest/md5/md5MessageDigest.hpp +++ b/src/vmime/security/digest/md5/md5MessageDigest.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,8 @@ namespace digest { namespace md5 { -class md5MessageDigest : public messageDigest -{ +class md5MessageDigest : public messageDigest { + public: md5MessageDigest(); @@ -63,8 +63,7 @@ protected: vmime_uint32 m_hash[4]; - union BlockType - { + union BlockType { vmime_uint32 b32[16]; vmime_uint8 b8[64]; }; diff --git a/src/vmime/security/digest/messageDigest.cpp b/src/vmime/security/digest/messageDigest.cpp index 18fc8628..d7e394fc 100644 --- a/src/vmime/security/digest/messageDigest.cpp +++ b/src/vmime/security/digest/messageDigest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,8 +31,8 @@ namespace security { namespace digest { -const string messageDigest::getHexDigest() const -{ +const string messageDigest::getHexDigest() const { + const byte_t* hash = getDigest(); const size_t len = getDigestLength(); @@ -41,8 +41,7 @@ const string messageDigest::getHexDigest() const std::ostringstream oss; oss.imbue(std::locale::classic()); - for (size_t i = 0 ; i < len ; ++i) - { + for (size_t i = 0 ; i < len ; ++i) { oss << hex[(hash[i] & 0xf0) >> 4]; oss << hex[(hash[i] & 0x0f)]; } diff --git a/src/vmime/security/digest/messageDigest.hpp b/src/vmime/security/digest/messageDigest.hpp index d17dfbc2..04138103 100644 --- a/src/vmime/security/digest/messageDigest.hpp +++ b/src/vmime/security/digest/messageDigest.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,8 @@ namespace digest { /** Computes message digests using standard algorithms, * such as MD5 or SHA. */ +class VMIME_EXPORT messageDigest : public object { -class VMIME_EXPORT messageDigest : public object -{ public: /** Updates the digest using the specified string. @@ -68,9 +67,11 @@ public: * @param offset offset to start from in the array of bytes * @param len number of bytes to use, starting at offset */ - virtual void update(const byte_t* buffer, - const size_t offset, - const size_t len) = 0; + virtual void update( + const byte_t* buffer, + const size_t offset, + const size_t len + ) = 0; /** Completes the hash computation by performing final operations * such as padding. @@ -87,16 +88,20 @@ public: * such as padding. This is equivalent to calling update() and * then finalize(). */ - virtual void finalize(const byte_t* buffer, - const size_t len) = 0; + virtual void finalize( + const byte_t* buffer, + const size_t len + ) = 0; /** Completes the hash computation by performing final operations * such as padding. This is equivalent to calling update() and * then finalize(). */ - virtual void finalize(const byte_t* buffer, - const size_t offset, - const size_t len) = 0; + virtual void finalize( + const byte_t* buffer, + const size_t offset, + const size_t len + ) = 0; /** Returns the length of the hash. * This is the length of the array returned by getDigest(). @@ -135,4 +140,3 @@ public: #endif // VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED - diff --git a/src/vmime/security/digest/messageDigestFactory.cpp b/src/vmime/security/digest/messageDigestFactory.cpp index 2831c5a1..2e499684 100644 --- a/src/vmime/security/digest/messageDigestFactory.cpp +++ b/src/vmime/security/digest/messageDigestFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,44 +33,42 @@ namespace security { namespace digest { -messageDigestFactory::messageDigestFactory() -{ +messageDigestFactory::messageDigestFactory() { + registerAlgorithm ("md5"); registerAlgorithm ("sha1"); } -messageDigestFactory::~messageDigestFactory() -{ +messageDigestFactory::~messageDigestFactory() { + } -messageDigestFactory* messageDigestFactory::getInstance() -{ +messageDigestFactory* messageDigestFactory::getInstance() { + static messageDigestFactory instance; - return (&instance); + return &instance; } -shared_ptr messageDigestFactory::create(const string& name) -{ - const MapType::const_iterator it = m_algos.find - (utility::stringUtils::toLower(name)); +shared_ptr messageDigestFactory::create(const string& name) { - if (it != m_algos.end()) + const MapType::const_iterator it = m_algos.find(utility::stringUtils::toLower(name)); + + if (it != m_algos.end()) { return (*it).second->create(); + } throw exceptions::no_digest_algorithm_available(name); } -const std::vector messageDigestFactory::getSupportedAlgorithms() const -{ +const std::vector messageDigestFactory::getSupportedAlgorithms() const { + std::vector res; - for (MapType::const_iterator it = m_algos.begin() ; - it != m_algos.end() ; ++it) - { + for (MapType::const_iterator it = m_algos.begin() ; it != m_algos.end() ; ++it) { res.push_back((*it).first); } @@ -81,4 +79,3 @@ const std::vector messageDigestFactory::getSupportedAlgorithms() const } // digest } // security } // vmime - diff --git a/src/vmime/security/digest/messageDigestFactory.hpp b/src/vmime/security/digest/messageDigestFactory.hpp index 15fd8a28..56a0cfe1 100644 --- a/src/vmime/security/digest/messageDigestFactory.hpp +++ b/src/vmime/security/digest/messageDigestFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,8 +38,8 @@ namespace digest { /** Creates instances of message digest algorithms. */ -class VMIME_EXPORT messageDigestFactory -{ +class VMIME_EXPORT messageDigestFactory { + private: messageDigestFactory(); @@ -51,20 +51,15 @@ public: private: - class digestAlgorithmFactory : public object - { - public: + struct digestAlgorithmFactory : public object { virtual shared_ptr create() const = 0; }; template - class digestAlgorithmFactoryImpl : public digestAlgorithmFactory - { - public: + struct digestAlgorithmFactoryImpl : public digestAlgorithmFactory { - shared_ptr create() const - { + shared_ptr create() const { return vmime::make_shared (); } }; @@ -80,10 +75,14 @@ public: * @param name algorithm name */ template - void registerAlgorithm(const string& name) - { - m_algos.insert(MapType::value_type(utility::stringUtils::toLower(name), - vmime::make_shared >())); + void registerAlgorithm(const string& name) { + + m_algos.insert( + MapType::value_type( + utility::stringUtils::toLower(name), + vmime::make_shared >() + ) + ); } /** Create a new algorithm instance from its name. @@ -109,4 +108,3 @@ public: #endif // VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED - diff --git a/src/vmime/security/digest/sha1/sha1MessageDigest.cpp b/src/vmime/security/digest/sha1/sha1MessageDigest.cpp index 9367008b..c098f144 100644 --- a/src/vmime/security/digest/sha1/sha1MessageDigest.cpp +++ b/src/vmime/security/digest/sha1/sha1MessageDigest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -58,20 +58,20 @@ namespace sha1 { #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); -sha1MessageDigest::sha1MessageDigest() -{ +sha1MessageDigest::sha1MessageDigest() { + init(); } -void sha1MessageDigest::reset() -{ +void sha1MessageDigest::reset() { + init(); } -void sha1MessageDigest::init() -{ +void sha1MessageDigest::init() { + m_state[0] = 0x67452301; m_state[1] = 0xefcdab89; m_state[2] = 0x98badcfe; @@ -83,48 +83,50 @@ void sha1MessageDigest::init() } -void sha1MessageDigest::update(const byte_t b) -{ +void sha1MessageDigest::update(const byte_t b) { + update(&b, 1); } -void sha1MessageDigest::update(const string& s) -{ +void sha1MessageDigest::update(const string& s) { + update(reinterpret_cast (s.data()), s.length()); } -void sha1MessageDigest::update(const byte_t* buffer, const size_t offset, const size_t len) -{ +void sha1MessageDigest::update(const byte_t* buffer, const size_t offset, const size_t len) { + update(buffer + offset, len); } -void sha1MessageDigest::update(const byte_t* buffer, const size_t len) -{ +void sha1MessageDigest::update(const byte_t* buffer, const size_t len) { + unsigned int i, j; j = (m_count[0] >> 3) & 63; - if ((m_count[0] += static_cast (len << 3)) < static_cast (len << 3)) + if ((m_count[0] += static_cast (len << 3)) < static_cast (len << 3)) { m_count[1]++; + } m_count[1] += static_cast (len >> 29); - if ((j + len) > 63) - { + if ((j + len) > 63) { + memcpy(&m_buffer[j], buffer, (i = 64 - j)); transform(m_state, m_buffer); - for ( ; i + 63 < len ; i += 64) + for ( ; i + 63 < len ; i += 64) { transform(m_state, &buffer[i]); + } j = 0; - } - else - { + + } else { + i = 0; } @@ -132,29 +134,31 @@ void sha1MessageDigest::update(const byte_t* buffer, const size_t len) } -void sha1MessageDigest::finalize() -{ +void sha1MessageDigest::finalize() { + unsigned int i, j; unsigned char finalcount[8]; - for (i = 0 ; i < 8 ; i++) - { - finalcount[i] = static_cast - ((m_count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); // Endian independent + for (i = 0 ; i < 8 ; i++) { + + finalcount[i] = static_cast ( + (m_count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255 // Endian independent + ); } update(reinterpret_cast ("\200"), 1); - while ((m_count[0] & 504) != 448) + while ((m_count[0] & 504) != 448) { update(reinterpret_cast ("\0"), 1); + } update(finalcount, 8); // Should cause a transform() - for (i = 0 ; i < 20 ; i++) - { - m_digest[i] = static_cast - ((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + for (i = 0 ; i < 20 ; i++) { + + m_digest[i] = static_cast ( + (m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255 + ); } // Wipe variables @@ -167,22 +171,25 @@ void sha1MessageDigest::finalize() } -void sha1MessageDigest::finalize(const string& s) -{ +void sha1MessageDigest::finalize(const string& s) { + finalize(reinterpret_cast (s.data()), s.length()); } -void sha1MessageDigest::finalize(const byte_t* buffer, const size_t len) -{ +void sha1MessageDigest::finalize(const byte_t* buffer, const size_t len) { + update(buffer, len); finalize(); } -void sha1MessageDigest::finalize(const byte_t* buffer, - const size_t offset, const size_t len) -{ +void sha1MessageDigest::finalize( + const byte_t* buffer, + const size_t offset, + const size_t len +) { + finalize(buffer + offset, len); } @@ -190,13 +197,14 @@ void sha1MessageDigest::finalize(const byte_t* buffer, /** Hash a single 512-bit block. * This is the core of the algorithm. */ -void sha1MessageDigest::transform - (unsigned int state[5], const unsigned char buffer[64]) -{ +void sha1MessageDigest::transform( + unsigned int state[5], + const unsigned char buffer[64] +) { + unsigned int a, b, c, d, e; - typedef union - { + typedef union { unsigned char c[64]; unsigned int l[16]; } CHAR64LONG16; @@ -250,14 +258,14 @@ void sha1MessageDigest::transform } -size_t sha1MessageDigest::getDigestLength() const -{ +size_t sha1MessageDigest::getDigestLength() const { + return 20; } -const byte_t* sha1MessageDigest::getDigest() const -{ +const byte_t* sha1MessageDigest::getDigest() const { + return m_digest; } @@ -266,5 +274,3 @@ const byte_t* sha1MessageDigest::getDigest() const } // digest } // security } // vmime - - diff --git a/src/vmime/security/digest/sha1/sha1MessageDigest.hpp b/src/vmime/security/digest/sha1/sha1MessageDigest.hpp index 1eb09c2f..19062365 100644 --- a/src/vmime/security/digest/sha1/sha1MessageDigest.hpp +++ b/src/vmime/security/digest/sha1/sha1MessageDigest.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,8 @@ namespace digest { namespace sha1 { -class sha1MessageDigest : public messageDigest -{ +class sha1MessageDigest : public messageDigest { + public: sha1MessageDigest(); diff --git a/src/vmime/security/sasl/SASLAuthenticator.hpp b/src/vmime/security/sasl/SASLAuthenticator.hpp index d4dc113c..a75bfa0f 100644 --- a/src/vmime/security/sasl/SASLAuthenticator.hpp +++ b/src/vmime/security/sasl/SASLAuthenticator.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -50,8 +50,8 @@ class SASLSession; * Usually, you should not inherit from this class, but instead from the * more convenient defaultSASLAuthenticator class. */ -class VMIME_EXPORT SASLAuthenticator : public authenticator -{ +class VMIME_EXPORT SASLAuthenticator : public authenticator { + public: /** This method is called to allow the client to choose the @@ -64,9 +64,10 @@ public: * @return ordered list of mechanism to use among the available * mechanisms (from the first to try to the last) */ - virtual const std::vector > getAcceptableMechanisms - (const std::vector >& available, - const shared_ptr & suggested) const = 0; + virtual const std::vector > getAcceptableMechanisms( + const std::vector >& available, + const shared_ptr & suggested + ) const = 0; /** Set the SASL session which is using this authenticator. * @@ -93,4 +94,3 @@ public: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/SASLContext.cpp b/src/vmime/security/sasl/SASLContext.cpp index 09ffed05..21745414 100644 --- a/src/vmime/security/sasl/SASLContext.cpp +++ b/src/vmime/security/sasl/SASLContext.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,63 +49,70 @@ namespace security { namespace sasl { -SASLContext::SASLContext() -{ - if (gsasl_init(&m_gsaslContext) != GSASL_OK) +SASLContext::SASLContext() { + + if (gsasl_init(&m_gsaslContext) != GSASL_OK) { throw std::bad_alloc(); + } } -SASLContext::~SASLContext() -{ +SASLContext::~SASLContext() { + gsasl_done(m_gsaslContext); } // static -shared_ptr SASLContext::create() -{ +shared_ptr SASLContext::create() { + return shared_ptr (new SASLContext()); } -shared_ptr SASLContext::createSession - (const string& serviceName, - const shared_ptr & auth, const shared_ptr & mech) -{ +shared_ptr SASLContext::createSession( + const string& serviceName, + const shared_ptr & auth, + const shared_ptr & mech +) { + return SASLSession::create (serviceName, dynamicCast (shared_from_this()), auth, mech); } -shared_ptr SASLContext::createMechanism(const string& name) -{ - return SASLMechanismFactory::getInstance()->create - (dynamicCast (shared_from_this()), name); +shared_ptr SASLContext::createMechanism(const string& name) { + + return SASLMechanismFactory::getInstance()->create( + dynamicCast (shared_from_this()), name + ); } -shared_ptr SASLContext::suggestMechanism - (const std::vector >& mechs) -{ - if (mechs.empty()) +shared_ptr SASLContext::suggestMechanism( + const std::vector >& mechs +) { + + if (mechs.empty()) { return null; + } std::ostringstream oss; - for (unsigned int i = 0 ; i < mechs.size() ; ++i) + for (unsigned int i = 0 ; i < mechs.size() ; ++i) { oss << mechs[i]->getName() << " "; + } const string mechList = oss.str(); - const char* suggested = gsasl_client_suggest_mechanism - (m_gsaslContext, mechList.c_str()); + const char* suggested = gsasl_client_suggest_mechanism(m_gsaslContext, mechList.c_str()); - if (suggested) - { - for (unsigned int i = 0 ; i < mechs.size() ; ++i) - { - if (mechs[i]->getName() == suggested) + if (suggested) { + + for (unsigned int i = 0 ; i < mechs.size() ; ++i) { + + if (mechs[i]->getName() == suggested) { return mechs[i]; + } } } @@ -113,8 +120,8 @@ shared_ptr SASLContext::suggestMechanism } -void SASLContext::decodeB64(const string& input, byte_t** output, size_t* outputLen) -{ +void SASLContext::decodeB64(const string& input, byte_t** output, size_t* outputLen) { + string res; utility::inputStreamStringAdapter is(input); @@ -134,8 +141,8 @@ void SASLContext::decodeB64(const string& input, byte_t** output, size_t* output } -const string SASLContext::encodeB64(const byte_t* input, const size_t inputLen) -{ +const string SASLContext::encodeB64(const byte_t* input, const size_t inputLen) { + string res; utility::inputStreamByteBufferAdapter is(input, inputLen); @@ -150,8 +157,8 @@ const string SASLContext::encodeB64(const byte_t* input, const size_t inputLen) } -const string SASLContext::getErrorMessage(const string& fname, const int code) -{ +const string SASLContext::getErrorMessage(const string& fname, const int code) { + string msg = fname + "() returned "; #define ERROR(x) \ @@ -159,45 +166,45 @@ const string SASLContext::getErrorMessage(const string& fname, const int code) switch (code) { - ERROR(GSASL_NEEDS_MORE) - ERROR(GSASL_UNKNOWN_MECHANISM) - ERROR(GSASL_MECHANISM_CALLED_TOO_MANY_TIMES) - ERROR(GSASL_MALLOC_ERROR) - ERROR(GSASL_BASE64_ERROR) - ERROR(GSASL_CRYPTO_ERROR) - ERROR(GSASL_SASLPREP_ERROR) - ERROR(GSASL_MECHANISM_PARSE_ERROR) - ERROR(GSASL_AUTHENTICATION_ERROR) - ERROR(GSASL_INTEGRITY_ERROR) - ERROR(GSASL_NO_CLIENT_CODE) - ERROR(GSASL_NO_SERVER_CODE) - ERROR(GSASL_NO_CALLBACK) - ERROR(GSASL_NO_ANONYMOUS_TOKEN) - ERROR(GSASL_NO_AUTHID) - ERROR(GSASL_NO_AUTHZID) - ERROR(GSASL_NO_PASSWORD) - ERROR(GSASL_NO_PASSCODE) - ERROR(GSASL_NO_PIN) - ERROR(GSASL_NO_SERVICE) - ERROR(GSASL_NO_HOSTNAME) - ERROR(GSASL_GSSAPI_RELEASE_BUFFER_ERROR) - ERROR(GSASL_GSSAPI_IMPORT_NAME_ERROR) - ERROR(GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR) - ERROR(GSASL_GSSAPI_ACCEPT_SEC_CONTEXT_ERROR) - ERROR(GSASL_GSSAPI_UNWRAP_ERROR) - ERROR(GSASL_GSSAPI_WRAP_ERROR) - ERROR(GSASL_GSSAPI_ACQUIRE_CRED_ERROR) - ERROR(GSASL_GSSAPI_DISPLAY_NAME_ERROR) - ERROR(GSASL_GSSAPI_UNSUPPORTED_PROTECTION_ERROR) - ERROR(GSASL_KERBEROS_V5_INIT_ERROR) - ERROR(GSASL_KERBEROS_V5_INTERNAL_ERROR) - ERROR(GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE) - ERROR(GSASL_SECURID_SERVER_NEED_NEW_PIN) + ERROR(GSASL_NEEDS_MORE) + ERROR(GSASL_UNKNOWN_MECHANISM) + ERROR(GSASL_MECHANISM_CALLED_TOO_MANY_TIMES) + ERROR(GSASL_MALLOC_ERROR) + ERROR(GSASL_BASE64_ERROR) + ERROR(GSASL_CRYPTO_ERROR) + ERROR(GSASL_SASLPREP_ERROR) + ERROR(GSASL_MECHANISM_PARSE_ERROR) + ERROR(GSASL_AUTHENTICATION_ERROR) + ERROR(GSASL_INTEGRITY_ERROR) + ERROR(GSASL_NO_CLIENT_CODE) + ERROR(GSASL_NO_SERVER_CODE) + ERROR(GSASL_NO_CALLBACK) + ERROR(GSASL_NO_ANONYMOUS_TOKEN) + ERROR(GSASL_NO_AUTHID) + ERROR(GSASL_NO_AUTHZID) + ERROR(GSASL_NO_PASSWORD) + ERROR(GSASL_NO_PASSCODE) + ERROR(GSASL_NO_PIN) + ERROR(GSASL_NO_SERVICE) + ERROR(GSASL_NO_HOSTNAME) + ERROR(GSASL_GSSAPI_RELEASE_BUFFER_ERROR) + ERROR(GSASL_GSSAPI_IMPORT_NAME_ERROR) + ERROR(GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR) + ERROR(GSASL_GSSAPI_ACCEPT_SEC_CONTEXT_ERROR) + ERROR(GSASL_GSSAPI_UNWRAP_ERROR) + ERROR(GSASL_GSSAPI_WRAP_ERROR) + ERROR(GSASL_GSSAPI_ACQUIRE_CRED_ERROR) + ERROR(GSASL_GSSAPI_DISPLAY_NAME_ERROR) + ERROR(GSASL_GSSAPI_UNSUPPORTED_PROTECTION_ERROR) + ERROR(GSASL_KERBEROS_V5_INIT_ERROR) + ERROR(GSASL_KERBEROS_V5_INTERNAL_ERROR) + ERROR(GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE) + ERROR(GSASL_SECURID_SERVER_NEED_NEW_PIN) - default: + default: - msg += "unknown error"; - break; + msg += "unknown error"; + break; } #undef ERROR @@ -212,4 +219,3 @@ const string SASLContext::getErrorMessage(const string& fname, const int code) #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/SASLContext.hpp b/src/vmime/security/sasl/SASLContext.hpp index 58d6a932..93d80ff9 100644 --- a/src/vmime/security/sasl/SASLContext.hpp +++ b/src/vmime/security/sasl/SASLContext.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ namespace sasl { /** An SASL client context. */ -class VMIME_EXPORT SASLContext : public object, public enable_shared_from_this -{ +class VMIME_EXPORT SASLContext : public object, public enable_shared_from_this { + friend class SASLSession; friend class builtinSASLMechanism; @@ -66,9 +66,11 @@ public: * @param mech SASL mechanism * @return a new SASL session */ - shared_ptr createSession - (const string& serviceName, - const shared_ptr & auth, const shared_ptr & mech); + shared_ptr createSession( + const string& serviceName, + const shared_ptr & auth, + const shared_ptr & mech + ); /** Create an instance of an SASL mechanism. * @@ -86,8 +88,9 @@ public: * @return suggested mechanism (usually the safest mechanism * supported by both the client and the server) */ - shared_ptr suggestMechanism - (const std::vector >& mechs); + shared_ptr suggestMechanism( + const std::vector >& mechs + ); /** Helper function for decoding Base64-encoded challenge. * @@ -131,4 +134,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/SASLMechanism.hpp b/src/vmime/security/sasl/SASLMechanism.hpp index 8e842c4f..a6e056df 100644 --- a/src/vmime/security/sasl/SASLMechanism.hpp +++ b/src/vmime/security/sasl/SASLMechanism.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ class SASLSession; /** An SASL mechanism. */ -class VMIME_EXPORT SASLMechanism : public object -{ +class VMIME_EXPORT SASLMechanism : public object { + public: /** Return the name of this mechanism. @@ -73,10 +73,13 @@ public: * authentication (in this case, the values in 'response' and * 'responseLen' are undetermined) */ - virtual bool step - (const shared_ptr & sess, - const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen) = 0; + virtual bool step( + const shared_ptr & sess, + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, + size_t* responseLen + ) = 0; /** Check whether authentication has completed. If false, more * calls to evaluateChallenge() are needed to complete the @@ -109,9 +112,13 @@ public: * the encoding of data (in this case, the values in 'output' and * 'outputLen' are undetermined) */ - virtual void encode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) = 0; + virtual void encode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ) = 0; /** Decode data according to negotiated SASL mechanism. This * might mean that data is integrity or privacy protected. @@ -126,9 +133,13 @@ public: * the encoding of data (in this case, the values in 'output' and * 'outputLen' are undetermined) */ - virtual void decode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) = 0; + virtual void decode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ) = 0; }; @@ -140,4 +151,3 @@ public: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/SASLMechanismFactory.cpp b/src/vmime/security/sasl/SASLMechanismFactory.cpp index 5ded627a..a2fbedbc 100644 --- a/src/vmime/security/sasl/SASLMechanismFactory.cpp +++ b/src/vmime/security/sasl/SASLMechanismFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,68 +47,73 @@ namespace security { namespace sasl { -SASLMechanismFactory::SASLMechanismFactory() -{ - if (gsasl_init(&m_gsaslContext) != GSASL_OK) +SASLMechanismFactory::SASLMechanismFactory() { + + if (gsasl_init(&m_gsaslContext) != GSASL_OK) { throw std::bad_alloc(); + } } -SASLMechanismFactory::~SASLMechanismFactory() -{ +SASLMechanismFactory::~SASLMechanismFactory() { + gsasl_done(m_gsaslContext); } // static -SASLMechanismFactory* SASLMechanismFactory::getInstance() -{ +SASLMechanismFactory* SASLMechanismFactory::getInstance() { + static SASLMechanismFactory instance; return &instance; } -shared_ptr SASLMechanismFactory::create - (const shared_ptr & ctx, const string& name_) -{ +shared_ptr SASLMechanismFactory::create( + const shared_ptr & ctx, + const string& name_ +) { + const string name(utility::stringUtils::toUpper(name_)); // Check for registered mechanisms MapType::iterator it = m_mechs.find(name); - if (it != m_mechs.end()) + if (it != m_mechs.end()) { return (*it).second->create(ctx, name); + } // Check for built-in mechanisms - if (isBuiltinMechanism(name)) + if (isBuiltinMechanism(name)) { return make_shared (ctx, name); + } throw exceptions::no_such_mechanism(name); return null; } -const std::vector SASLMechanismFactory::getSupportedMechanisms() const -{ +const std::vector SASLMechanismFactory::getSupportedMechanisms() const { + std::vector list; // Registered mechanisms for (MapType::const_iterator it = m_mechs.begin() ; - it != m_mechs.end() ; ++it) - { + it != m_mechs.end() ; ++it) { + list.push_back((*it).first); } // Built-in mechanisms char* out = 0; - if (gsasl_client_mechlist(m_gsaslContext, &out) == GSASL_OK) - { + if (gsasl_client_mechlist(m_gsaslContext, &out) == GSASL_OK) { + // 'out' contains SASL mechanism names, separated by spaces - for (char *start = out, *p = out ; ; ++p) - { - if (*p == ' ' || !*p) - { + for (char *start = out, *p = out ; ; ++p) { + + if (*p == ' ' || !*p) { + list.push_back(string(start, p)); start = p + 1; @@ -124,14 +129,14 @@ const std::vector SASLMechanismFactory::getSupportedMechanisms() const } -bool SASLMechanismFactory::isMechanismSupported(const string& name) const -{ +bool SASLMechanismFactory::isMechanismSupported(const string& name) const { + return isBuiltinMechanism(name) || m_mechs.find(name) != m_mechs.end(); } -bool SASLMechanismFactory::isBuiltinMechanism(const string& name) const -{ +bool SASLMechanismFactory::isBuiltinMechanism(const string& name) const { + return gsasl_client_support_p(m_gsaslContext, name.c_str()) != 0; } @@ -142,4 +147,3 @@ bool SASLMechanismFactory::isBuiltinMechanism(const string& name) const #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/SASLMechanismFactory.hpp b/src/vmime/security/sasl/SASLMechanismFactory.hpp index d83b37a1..af76c96d 100644 --- a/src/vmime/security/sasl/SASLMechanismFactory.hpp +++ b/src/vmime/security/sasl/SASLMechanismFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,29 +49,29 @@ class SASLContext; /** Constructs SASL mechanism objects. */ -class VMIME_EXPORT SASLMechanismFactory : public object -{ +class VMIME_EXPORT SASLMechanismFactory : public object { + private: SASLMechanismFactory(); ~SASLMechanismFactory(); - class registeredMechanism : public object - { - public: + struct registeredMechanism : public object { - virtual shared_ptr create - (const shared_ptr & ctx, const string& name) = 0; + virtual shared_ptr create( + const shared_ptr & ctx, const string& name + ) = 0; }; template - class registeredMechanismImpl : public registeredMechanism - { - public: + struct registeredMechanismImpl : public registeredMechanism { + + shared_ptr create( + const shared_ptr & ctx, + const string& name + ) { - shared_ptr create(const shared_ptr & ctx, const string& name) - { return vmime::make_shared (ctx, name); } }; @@ -89,10 +89,14 @@ public: * @param name mechanism name */ template - void registerMechanism(const string& name) - { - m_mechs.insert(MapType::value_type(name, - vmime::make_shared >())); + void registerMechanism(const string& name) { + + m_mechs.insert( + MapType::value_type( + name, + vmime::make_shared >() + ) + ); } /** Create a mechanism object given its name. @@ -149,4 +153,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/SASLSession.cpp b/src/vmime/security/sasl/SASLSession.cpp index 28446fe3..7498b461 100644 --- a/src/vmime/security/sasl/SASLSession.cpp +++ b/src/vmime/security/sasl/SASLSession.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,13 +43,22 @@ namespace security { namespace sasl { -SASLSession::SASLSession(const string& serviceName, const shared_ptr & ctx, - const shared_ptr & auth, const shared_ptr & mech) - : m_serviceName(serviceName), m_context(ctx), m_auth(auth), - m_mech(mech), m_gsaslContext(0), m_gsaslSession(0) -{ - if (gsasl_init(&m_gsaslContext) != GSASL_OK) +SASLSession::SASLSession( + const string& serviceName, + const shared_ptr & ctx, + const shared_ptr & auth, + const shared_ptr & mech +) + : m_serviceName(serviceName), + m_context(ctx), + m_auth(auth), + m_mech(mech), + m_gsaslContext(0), + m_gsaslSession(0) { + + if (gsasl_init(&m_gsaslContext) != GSASL_OK) { throw std::bad_alloc(); + } gsasl_client_start(m_gsaslContext, mech->getName().c_str(), &m_gsaslSession); @@ -58,8 +67,8 @@ SASLSession::SASLSession(const string& serviceName, const shared_ptr SASLSession::create - (const string& serviceName, const shared_ptr & ctx, - const shared_ptr & auth, const shared_ptr & mech) -{ +shared_ptr SASLSession::create( + const string& serviceName, + const shared_ptr & ctx, + const shared_ptr & auth, + const shared_ptr & mech +) { + return shared_ptr (new SASLSession(serviceName, ctx, auth, mech)); } -void SASLSession::init() -{ +void SASLSession::init() { + shared_ptr saslAuth = dynamicCast (m_auth); - if (saslAuth) - { + if (saslAuth) { saslAuth->setSASLMechanism(m_mech); saslAuth->setSASLSession(dynamicCast (shared_from_this())); } } -shared_ptr SASLSession::getAuthenticator() -{ +shared_ptr SASLSession::getAuthenticator() { + return m_auth; } -shared_ptr SASLSession::getMechanism() -{ +shared_ptr SASLSession::getMechanism() { + return m_mech; } -shared_ptr SASLSession::getContext() -{ +shared_ptr SASLSession::getContext() { + return m_context; } -bool SASLSession::evaluateChallenge - (const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen) -{ - return m_mech->step(dynamicCast (shared_from_this()), - challenge, challengeLen, response, responseLen); +bool SASLSession::evaluateChallenge( + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, + size_t* responseLen +) { + + return m_mech->step( + dynamicCast (shared_from_this()), + challenge, challengeLen, response, responseLen + ); } -shared_ptr SASLSession::getSecuredSocket(const shared_ptr & sok) -{ +shared_ptr SASLSession::getSecuredSocket(const shared_ptr & sok) { + return make_shared (dynamicCast (shared_from_this()), sok); } -const string SASLSession::getServiceName() const -{ +const string SASLSession::getServiceName() const { + return m_serviceName; } // static -int SASLSession::gsaslCallback - (Gsasl* ctx, Gsasl_session* sctx, Gsasl_property prop) -{ +int SASLSession::gsaslCallback( + Gsasl* ctx, + Gsasl_session* sctx, + Gsasl_property prop +) { + SASLSession* sess = reinterpret_cast (gsasl_callback_hook_get(ctx)); - if (!sess) return GSASL_AUTHENTICATION_ERROR; + + if (!sess) { + return GSASL_AUTHENTICATION_ERROR; + } shared_ptr auth = sess->getAuthenticator(); - try - { + try { + string res; - switch (prop) - { - case GSASL_AUTHID: + switch (prop) { - res = auth->getUsername(); - break; + case GSASL_AUTHID: - case GSASL_PASSWORD: + res = auth->getUsername(); + break; - res = auth->getPassword(); - break; + case GSASL_PASSWORD: - case GSASL_ANONYMOUS_TOKEN: + res = auth->getPassword(); + break; - res = auth->getAnonymousToken(); - break; + case GSASL_ANONYMOUS_TOKEN: - case GSASL_HOSTNAME: + res = auth->getAnonymousToken(); + break; - res = auth->getHostname(); - break; + case GSASL_HOSTNAME: - case GSASL_SERVICE: + res = auth->getHostname(); + break; - res = auth->getServiceName(); - break; + case GSASL_SERVICE: - case GSASL_AUTHZID: - case GSASL_GSSAPI_DISPLAY_NAME: - case GSASL_PASSCODE: - case GSASL_SUGGESTED_PIN: - case GSASL_PIN: - case GSASL_REALM: + res = auth->getServiceName(); + break; - default: + case GSASL_AUTHZID: + case GSASL_GSSAPI_DISPLAY_NAME: + case GSASL_PASSCODE: + case GSASL_SUGGESTED_PIN: + case GSASL_PIN: + case GSASL_REALM: - return GSASL_NO_CALLBACK; + default: + + return GSASL_NO_CALLBACK; } gsasl_property_set(sctx, prop, res.c_str()); return GSASL_OK; - } - //catch (exceptions::no_auth_information&) - catch (...) - { + + } catch (...) { + return GSASL_NO_CALLBACK; } } @@ -198,4 +219,3 @@ int SASLSession::gsaslCallback #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/SASLSession.hpp b/src/vmime/security/sasl/SASLSession.hpp index 65387bd3..7fc7225c 100644 --- a/src/vmime/security/sasl/SASLSession.hpp +++ b/src/vmime/security/sasl/SASLSession.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -49,8 +49,8 @@ class SASLContext; /** An SASL client session. */ -class VMIME_EXPORT SASLSession : public object, public enable_shared_from_this -{ +class VMIME_EXPORT SASLSession : public object, public enable_shared_from_this { + friend class builtinSASLMechanism; friend class SASLSocket; @@ -65,9 +65,12 @@ public: * @param auth authenticator to use for this session * @param mech SASL mechanism */ - static shared_ptr create - (const string& serviceName, const shared_ptr & ctx, - const shared_ptr & auth, const shared_ptr & mech); + static shared_ptr create( + const string& serviceName, + const shared_ptr & ctx, + const shared_ptr & auth, + const shared_ptr & mech + ); /** Initialize this SASL session. This must be called before * calling any other method on this object (except accessors). @@ -112,9 +115,12 @@ public: * authentication (in this case, the values in 'response' and * 'responseLen' are undetermined) */ - bool evaluateChallenge - (const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen); + bool evaluateChallenge( + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, + size_t* responseLen + ); /** Return a socket in which transmitted data is integrity * and/or privacy protected, depending on the QOP (Quality of @@ -135,9 +141,12 @@ public: private: - SASLSession - (const string& serviceName, const shared_ptr & ctx, - const shared_ptr & auth, const shared_ptr & mech); + SASLSession( + const string& serviceName, + const shared_ptr & ctx, + const shared_ptr & auth, + const shared_ptr & mech + ); const string m_serviceName; @@ -169,4 +178,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/SASLSocket.cpp b/src/vmime/security/sasl/SASLSocket.cpp index 4312ab35..0dbafd80 100644 --- a/src/vmime/security/sasl/SASLSocket.cpp +++ b/src/vmime/security/sasl/SASLSocket.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,110 +46,119 @@ namespace sasl { -SASLSocket::SASLSocket(const shared_ptr & sess, const shared_ptr & wrapped) - : m_session(sess), m_wrapped(wrapped), - m_pendingBuffer(0), m_pendingPos(0), m_pendingLen(0) -{ +SASLSocket::SASLSocket( + const shared_ptr & sess, + const shared_ptr & wrapped +) + : m_session(sess), + m_wrapped(wrapped), + m_pendingBuffer(0), + m_pendingPos(0), + m_pendingLen(0) { + } -SASLSocket::~SASLSocket() -{ - if (m_pendingBuffer) +SASLSocket::~SASLSocket() { + + if (m_pendingBuffer) { delete [] m_pendingBuffer; + } } -void SASLSocket::connect(const string& address, const port_t port) -{ +void SASLSocket::connect(const string& address, const port_t port) { + m_wrapped->connect(address, port); } -void SASLSocket::disconnect() -{ +void SASLSocket::disconnect() { + m_wrapped->disconnect(); } -bool SASLSocket::isConnected() const -{ +bool SASLSocket::isConnected() const { + return m_wrapped->isConnected(); } -size_t SASLSocket::getBlockSize() const -{ +size_t SASLSocket::getBlockSize() const { + return m_wrapped->getBlockSize(); } -const string SASLSocket::getPeerName() const -{ +const string SASLSocket::getPeerName() const { + return m_wrapped->getPeerName(); } -const string SASLSocket::getPeerAddress() const -{ +const string SASLSocket::getPeerAddress() const { + return m_wrapped->getPeerAddress(); } -shared_ptr SASLSocket::getTimeoutHandler() -{ +shared_ptr SASLSocket::getTimeoutHandler() { + return m_wrapped->getTimeoutHandler(); } -void SASLSocket::setTracer(const shared_ptr & tracer) -{ +void SASLSocket::setTracer(const shared_ptr & tracer) { + m_wrapped->setTracer(tracer); } -shared_ptr SASLSocket::getTracer() -{ +shared_ptr SASLSocket::getTracer() { + return m_wrapped->getTracer(); } -bool SASLSocket::waitForRead(const int msecs) -{ +bool SASLSocket::waitForRead(const int msecs) { + return m_wrapped->waitForRead(msecs); } -bool SASLSocket::waitForWrite(const int msecs) -{ +bool SASLSocket::waitForWrite(const int msecs) { + return m_wrapped->waitForWrite(msecs); } -void SASLSocket::receive(string& buffer) -{ +void SASLSocket::receive(string& buffer) { + const size_t n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer)); buffer = utility::stringUtils::makeStringFromBytes(m_recvBuffer, n); } -size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) -{ - if (m_pendingLen != 0) - { +size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) { + + if (m_pendingLen != 0) { + const size_t copyLen = (count >= m_pendingLen ? m_pendingLen : count); - std::copy(m_pendingBuffer + m_pendingPos, - m_pendingBuffer + m_pendingPos + copyLen, - buffer); + std::copy( + m_pendingBuffer + m_pendingPos, + m_pendingBuffer + m_pendingPos + copyLen, + buffer + ); m_pendingLen -= copyLen; m_pendingPos += copyLen; - if (m_pendingLen == 0) - { + if (m_pendingLen == 0) { + delete [] m_pendingBuffer; m_pendingBuffer = 0; @@ -165,13 +174,12 @@ size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) byte_t* output = 0; size_t outputLen = 0; - m_session->getMechanism()->decode - (m_session, buffer, n, &output, &outputLen); + m_session->getMechanism()->decode(m_session, buffer, n, &output, &outputLen); // If we can not copy all decoded data into the output buffer, put // remaining data into a pending buffer for next calls to receive() - if (outputLen > count) - { + if (outputLen > count) { + std::copy(output, output + count, buffer); m_pendingBuffer = output; @@ -179,9 +187,9 @@ size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) m_pendingPos = count; return count; - } - else - { + + } else { + std::copy(output, output + outputLen, buffer); delete [] output; @@ -191,32 +199,33 @@ size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) } -void SASLSocket::send(const string& buffer) -{ +void SASLSocket::send(const string& buffer) { + sendRaw(reinterpret_cast (buffer.data()), buffer.length()); } -void SASLSocket::send(const char* str) -{ +void SASLSocket::send(const char* str) { + sendRaw(reinterpret_cast (str), strlen(str)); } -void SASLSocket::sendRaw(const byte_t* buffer, const size_t count) -{ +void SASLSocket::sendRaw(const byte_t* buffer, const size_t count) { + byte_t* output = 0; size_t outputLen = 0; - m_session->getMechanism()->encode - (m_session, buffer, count, &output, &outputLen); + m_session->getMechanism()->encode( + m_session, buffer, count, &output, &outputLen + ); + + try { - try - { m_wrapped->sendRaw(output, outputLen); - } - catch (...) - { + + } catch (...) { + delete [] output; throw; } @@ -225,22 +234,21 @@ void SASLSocket::sendRaw(const byte_t* buffer, const size_t count) } -size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) -{ +size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) { + byte_t* output = 0; size_t outputLen = 0; - m_session->getMechanism()->encode - (m_session, buffer, count, &output, &outputLen); + m_session->getMechanism()->encode(m_session, buffer, count, &output, &outputLen); size_t bytesSent = 0; - try - { + try { + bytesSent = m_wrapped->sendRawNonBlocking(output, outputLen); - } - catch (...) - { + + } catch (...) { + delete [] output; throw; } @@ -251,8 +259,8 @@ size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) } -unsigned int SASLSocket::getStatus() const -{ +unsigned int SASLSocket::getStatus() const { + return m_wrapped->getStatus(); } @@ -263,4 +271,3 @@ unsigned int SASLSocket::getStatus() const #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/SASLSocket.hpp b/src/vmime/security/sasl/SASLSocket.hpp index 7a732394..ac0e89e9 100644 --- a/src/vmime/security/sasl/SASLSocket.hpp +++ b/src/vmime/security/sasl/SASLSocket.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,11 +46,15 @@ class SASLSession; /** A socket which provides data integrity and/or privacy protection. */ -class VMIME_EXPORT SASLSocket : public net::socket -{ +class VMIME_EXPORT SASLSocket : public net::socket { + public: - SASLSocket(const shared_ptr & sess, const shared_ptr & wrapped); + SASLSocket( + const shared_ptr & sess, + const shared_ptr & wrapped + ); + ~SASLSocket(); void connect(const string& address, const port_t port); @@ -102,4 +106,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp index fe36bbab..ecc715a1 100644 --- a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp +++ b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,48 +40,47 @@ namespace sasl { XOAuth2SASLAuthenticator::XOAuth2SASLAuthenticator(const Mode mode) - : m_mode(mode) -{ + : m_mode(mode) { + } -XOAuth2SASLAuthenticator::~XOAuth2SASLAuthenticator() -{ +XOAuth2SASLAuthenticator::~XOAuth2SASLAuthenticator() { + } const std::vector > - XOAuth2SASLAuthenticator::getAcceptableMechanisms - (const std::vector >& available, - const shared_ptr & suggested) const -{ - if (m_mode == MODE_EXCLUSIVE) - { + XOAuth2SASLAuthenticator::getAcceptableMechanisms( + const std::vector >& available, + const shared_ptr & suggested + ) const { + + if (m_mode == MODE_EXCLUSIVE) { + std::vector > mechs; - for (size_t i = available.size() ; i != 0 ; --i) - { + for (size_t i = available.size() ; i != 0 ; --i) { + shared_ptr mech = available[i - 1]; - if ("XOAUTH2" == mech->getName()) - { + if ("XOAUTH2" == mech->getName()) { // Only allow XOAuth2 mechs.push_back(mech); } } return mechs; - } - else - { + + } else { + shared_ptr newSuggested(suggested); - for (size_t i = available.size() ; i != 0 ; --i) - { + for (size_t i = available.size() ; i != 0 ; --i) { + shared_ptr mech = available[i - 1]; - if ("XOAUTH2" == mech->getName()) - { + if ("XOAUTH2" == mech->getName()) { // Suggest using XOAuth2 newSuggested = mech; } diff --git a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp index 84fa8917..e4d3d837 100644 --- a/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp +++ b/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,12 +43,11 @@ namespace sasl { * for XOAuth2 authentication mechanisms (username and access token). * This authenticator force using the XOAUTH2 mechanism. */ -class VMIME_EXPORT XOAuth2SASLAuthenticator : public defaultSASLAuthenticator -{ +class VMIME_EXPORT XOAuth2SASLAuthenticator : public defaultSASLAuthenticator { + public: - enum Mode - { + enum Mode { MODE_SUGGEST, /**< Try XOAUTH2 before other mechanisms. */ MODE_EXCLUSIVE /**< Use XOAUTH2 and nothing else. */ }; @@ -57,9 +56,10 @@ public: XOAuth2SASLAuthenticator(const Mode mode); ~XOAuth2SASLAuthenticator(); - const std::vector > getAcceptableMechanisms - (const std::vector >& available, - const shared_ptr & suggested) const; + const std::vector > getAcceptableMechanisms( + const std::vector >& available, + const shared_ptr & suggested + ) const; private: @@ -75,4 +75,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp b/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp index c699fa83..e5ecd4bd 100644 --- a/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp +++ b/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,28 +42,35 @@ namespace security { namespace sasl { -XOAuth2SASLMechanism::XOAuth2SASLMechanism(const shared_ptr & ctx, const string& /* name */) - : m_context(ctx), m_complete(false) -{ +XOAuth2SASLMechanism::XOAuth2SASLMechanism( + const shared_ptr & ctx, + const string& /* name */ +) + : m_context(ctx), + m_complete(false) { + } -XOAuth2SASLMechanism::~XOAuth2SASLMechanism() -{ +XOAuth2SASLMechanism::~XOAuth2SASLMechanism() { + } -const string XOAuth2SASLMechanism::getName() const -{ +const string XOAuth2SASLMechanism::getName() const { + return "XOAUTH2"; } -bool XOAuth2SASLMechanism::step - (const shared_ptr & sess, - const byte_t* /* challenge */, const size_t /* challengeLen */, - byte_t** response, size_t* responseLen) -{ +bool XOAuth2SASLMechanism::step( + const shared_ptr & sess, + const byte_t* /* challenge */, + const size_t /* challengeLen */, + byte_t** response, + size_t* responseLen +) { + // Build initial response // // The SASL XOAUTH2 initial client response has the following format: @@ -94,23 +101,26 @@ bool XOAuth2SASLMechanism::step } -bool XOAuth2SASLMechanism::isComplete() const -{ +bool XOAuth2SASLMechanism::isComplete() const { + return m_complete; } -bool XOAuth2SASLMechanism::hasInitialResponse() const -{ +bool XOAuth2SASLMechanism::hasInitialResponse() const { + return true; } -void XOAuth2SASLMechanism::encode - (const shared_ptr & /* sess */, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) -{ +void XOAuth2SASLMechanism::encode( + const shared_ptr & /* sess */, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen +) { + // No encoding performed, just copy input bytes byte_t* res = new byte_t[inputLen]; std::copy(input, input + inputLen, res); @@ -120,11 +130,14 @@ void XOAuth2SASLMechanism::encode } -void XOAuth2SASLMechanism::decode - (const shared_ptr & /* sess */, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) -{ +void XOAuth2SASLMechanism::decode( + const shared_ptr & /* sess */, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen +) { + // No decoding performed, just copy input bytes byte_t* res = new byte_t[inputLen]; std::copy(input, input + inputLen, res); diff --git a/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp b/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp index 5a49267e..eacbb0ae 100644 --- a/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp +++ b/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,8 +44,8 @@ class SASLContext; /** SASL XOAUTH2 mechanism, used by GMail. */ -class VMIME_EXPORT XOAuth2SASLMechanism : public SASLMechanism -{ +class VMIME_EXPORT XOAuth2SASLMechanism : public SASLMechanism { + public: XOAuth2SASLMechanism(const shared_ptr & ctx, const string& name); @@ -54,21 +54,33 @@ public: const string getName() const; - bool step(const shared_ptr & sess, - const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen); + bool step( + const shared_ptr & sess, + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, + size_t* responseLen + ); bool isComplete() const; bool hasInitialResponse() const; - void encode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen); + void encode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ); - void decode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen); + void decode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ); private: @@ -88,4 +100,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/builtinSASLMechanism.cpp b/src/vmime/security/sasl/builtinSASLMechanism.cpp index cbbb98c3..846e2ccf 100644 --- a/src/vmime/security/sasl/builtinSASLMechanism.cpp +++ b/src/vmime/security/sasl/builtinSASLMechanism.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,113 +45,130 @@ namespace security { namespace sasl { -builtinSASLMechanism::builtinSASLMechanism(const shared_ptr & ctx, const string& name) - : m_context(ctx), m_name(name), m_complete(false) -{ +builtinSASLMechanism::builtinSASLMechanism( + const shared_ptr & ctx, + const string& name +) + : m_context(ctx), + m_name(name), + m_complete(false) { + } -builtinSASLMechanism::~builtinSASLMechanism() -{ +builtinSASLMechanism::~builtinSASLMechanism() { + } -const string builtinSASLMechanism::getName() const -{ +const string builtinSASLMechanism::getName() const { + return m_name; } -bool builtinSASLMechanism::step - (const shared_ptr & sess, const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen) -{ +bool builtinSASLMechanism::step( + const shared_ptr & sess, + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, + size_t* responseLen +) { + char* output = 0; size_t outputLen = 0; - const int result = gsasl_step(sess->m_gsaslSession, + const int result = gsasl_step( + sess->m_gsaslSession, reinterpret_cast (challenge), challengeLen, - &output, &outputLen); + &output, &outputLen + ); + + if (result == GSASL_OK || result == GSASL_NEEDS_MORE) { - if (result == GSASL_OK || result == GSASL_NEEDS_MORE) - { byte_t* res = new byte_t[outputLen]; - for (size_t i = 0 ; i < outputLen ; ++i) + for (size_t i = 0 ; i < outputLen ; ++i) { res[i] = output[i]; + } *response = res; *responseLen = outputLen; gsasl_free(output); - } - else - { + + } else { + *response = 0; *responseLen = 0; } - if (result == GSASL_OK) - { + if (result == GSASL_OK) { + // Authentication process completed m_complete = true; return true; - } - else if (result == GSASL_NEEDS_MORE) - { + + } else if (result == GSASL_NEEDS_MORE) { + // Continue authentication process return false; - } - else if (result == GSASL_MALLOC_ERROR) - { + + } else if (result == GSASL_MALLOC_ERROR) { + throw std::bad_alloc(); - } - else - { - throw exceptions::sasl_exception("Error when processing challenge: " - + SASLContext::getErrorMessage("gsasl_step", result)); + + } else { + + throw exceptions::sasl_exception( + "Error when processing challenge: " + + SASLContext::getErrorMessage("gsasl_step", result) + ); } } -bool builtinSASLMechanism::isComplete() const -{ +bool builtinSASLMechanism::isComplete() const { + return m_complete; } -bool builtinSASLMechanism::hasInitialResponse() const -{ +bool builtinSASLMechanism::hasInitialResponse() const { + // It seems GNU SASL does not support initial response return false; } -void builtinSASLMechanism::encode - (const shared_ptr & sess, const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) -{ +void builtinSASLMechanism::encode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen +) { + char* coutput = 0; size_t coutputLen = 0; - if (gsasl_encode(sess->m_gsaslSession, - reinterpret_cast (input), inputLen, - &coutput, &coutputLen) != GSASL_OK) - { + if (gsasl_encode(sess->m_gsaslSession, reinterpret_cast (input), inputLen, + &coutput, &coutputLen) != GSASL_OK) { + throw exceptions::sasl_exception("Encoding error."); } - try - { + try { + byte_t* res = new byte_t[coutputLen]; std::copy(coutput, coutput + coutputLen, res); *output = res; *outputLen = static_cast (coutputLen); - } - catch (...) - { + + } catch (...) { + gsasl_free(coutput); throw; } @@ -160,19 +177,22 @@ void builtinSASLMechanism::encode } -void builtinSASLMechanism::decode - (const shared_ptr & sess, const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen) -{ +void builtinSASLMechanism::decode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen +) { + char* coutput = 0; size_t coutputLen = 0; - try - { - if (gsasl_decode(sess->m_gsaslSession, - reinterpret_cast (input), inputLen, - &coutput, &coutputLen) != GSASL_OK) - { + try { + + if (gsasl_decode(sess->m_gsaslSession, reinterpret_cast (input), inputLen, + &coutput, &coutputLen) != GSASL_OK) { + throw exceptions::sasl_exception("Decoding error."); } @@ -182,9 +202,9 @@ void builtinSASLMechanism::decode *output = res; *outputLen = static_cast (coutputLen); - } - catch (...) - { + + } catch (...) { + gsasl_free(coutput); throw; } @@ -199,4 +219,3 @@ void builtinSASLMechanism::decode #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/builtinSASLMechanism.hpp b/src/vmime/security/sasl/builtinSASLMechanism.hpp index a82c74af..2e412d6c 100644 --- a/src/vmime/security/sasl/builtinSASLMechanism.hpp +++ b/src/vmime/security/sasl/builtinSASLMechanism.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,8 +45,8 @@ class SASLContext; /** A built-in authentication mechanism that relies on * the GNU SASL library. */ -class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism -{ +class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism { + public: builtinSASLMechanism(const shared_ptr & ctx, const string& name); @@ -55,21 +55,32 @@ public: const string getName() const; - bool step(const shared_ptr & sess, - const byte_t* challenge, const size_t challengeLen, - byte_t** response, size_t* responseLen); + bool step( + const shared_ptr & sess, + const byte_t* challenge, + const size_t challengeLen, + byte_t** response, size_t* responseLen + ); bool isComplete() const; bool hasInitialResponse() const; - void encode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen); + void encode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ); - void decode(const shared_ptr & sess, - const byte_t* input, const size_t inputLen, - byte_t** output, size_t* outputLen); + void decode( + const shared_ptr & sess, + const byte_t* input, + const size_t inputLen, + byte_t** output, + size_t* outputLen + ); private: @@ -92,4 +103,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED - diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp index 2dbc0399..ebd7e682 100644 --- a/src/vmime/security/sasl/defaultSASLAuthenticator.cpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,111 +41,112 @@ namespace security { namespace sasl { -defaultSASLAuthenticator::defaultSASLAuthenticator() -{ +defaultSASLAuthenticator::defaultSASLAuthenticator() { + } -defaultSASLAuthenticator::~defaultSASLAuthenticator() -{ +defaultSASLAuthenticator::~defaultSASLAuthenticator() { + } -const std::vector > - defaultSASLAuthenticator::getAcceptableMechanisms - (const std::vector >& available, - const shared_ptr & suggested) const -{ - if (suggested) - { +const std::vector > defaultSASLAuthenticator::getAcceptableMechanisms( + const std::vector >& available, + const shared_ptr & suggested +) const { + + if (suggested) { + std::vector > res; res.push_back(suggested); - for (unsigned int i = 0 ; i < available.size() ; ++i) - { - if (available[i]->getName() != suggested->getName()) + for (unsigned int i = 0 ; i < available.size() ; ++i) { + + if (available[i]->getName() != suggested->getName()) { res.push_back(available[i]); + } } return res; - } - else - { + + } else { + return available; } } -const string defaultSASLAuthenticator::getUsername() const -{ +const string defaultSASLAuthenticator::getUsername() const { + return m_default.getUsername(); } -const string defaultSASLAuthenticator::getPassword() const -{ +const string defaultSASLAuthenticator::getPassword() const { + return m_default.getPassword(); } -const string defaultSASLAuthenticator::getAccessToken() const -{ +const string defaultSASLAuthenticator::getAccessToken() const { + return m_default.getAccessToken(); } -const string defaultSASLAuthenticator::getHostname() const -{ +const string defaultSASLAuthenticator::getHostname() const { + return m_default.getHostname(); } -const string defaultSASLAuthenticator::getAnonymousToken() const -{ +const string defaultSASLAuthenticator::getAnonymousToken() const { + return m_default.getAnonymousToken(); } -const string defaultSASLAuthenticator::getServiceName() const -{ +const string defaultSASLAuthenticator::getServiceName() const { + return m_saslSession.lock()->getServiceName(); } -void defaultSASLAuthenticator::setService(const shared_ptr & serv) -{ +void defaultSASLAuthenticator::setService(const shared_ptr & serv) { + m_service = serv; m_default.setService(serv); } -weak_ptr defaultSASLAuthenticator::getService() const -{ +weak_ptr defaultSASLAuthenticator::getService() const { + return m_service; } -void defaultSASLAuthenticator::setSASLSession(const shared_ptr & sess) -{ +void defaultSASLAuthenticator::setSASLSession(const shared_ptr & sess) { + m_saslSession = sess; } -shared_ptr defaultSASLAuthenticator::getSASLSession() const -{ +shared_ptr defaultSASLAuthenticator::getSASLSession() const { + return m_saslSession.lock(); } -void defaultSASLAuthenticator::setSASLMechanism(const shared_ptr & mech) -{ +void defaultSASLAuthenticator::setSASLMechanism(const shared_ptr & mech) { + m_saslMech = mech; } -shared_ptr defaultSASLAuthenticator::getSASLMechanism() const -{ +shared_ptr defaultSASLAuthenticator::getSASLMechanism() const { + return m_saslMech; } @@ -156,4 +157,3 @@ shared_ptr defaultSASLAuthenticator::getSASLMechanism() const #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT - diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.hpp b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp index f73849be..368e9eff 100644 --- a/src/vmime/security/sasl/defaultSASLAuthenticator.hpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,16 +43,17 @@ namespace sasl { /** An authenticator that is capable of providing information * for simple authentication mechanisms (username and password). */ -class VMIME_EXPORT defaultSASLAuthenticator : public SASLAuthenticator -{ +class VMIME_EXPORT defaultSASLAuthenticator : public SASLAuthenticator { + public: defaultSASLAuthenticator(); ~defaultSASLAuthenticator(); - const std::vector > getAcceptableMechanisms - (const std::vector >& available, - const shared_ptr & suggested) const; + const std::vector > getAcceptableMechanisms( + const std::vector >& available, + const shared_ptr & suggested + ) const; const string getUsername() const; const string getPassword() const; @@ -88,4 +89,3 @@ private: #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT #endif // VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED - diff --git a/src/vmime/streamContentHandler.cpp b/src/vmime/streamContentHandler.cpp index 230a802a..e35bcd7c 100644 --- a/src/vmime/streamContentHandler.cpp +++ b/src/vmime/streamContentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,77 +29,91 @@ #include "vmime/utility/streamUtils.hpp" -namespace vmime -{ +namespace vmime { streamContentHandler::streamContentHandler() - : m_encoding(NO_ENCODING), m_stream(null), m_length(0) -{ + : m_encoding(NO_ENCODING), + m_stream(null), + m_length(0) { + } -streamContentHandler::streamContentHandler(const shared_ptr & is, - const size_t length, const vmime::encoding& enc) -{ +streamContentHandler::streamContentHandler( + const shared_ptr & is, + const size_t length, + const vmime::encoding& enc +) { + setData(is, length, enc); } -streamContentHandler::~streamContentHandler() -{ +streamContentHandler::~streamContentHandler() { + } streamContentHandler::streamContentHandler(const streamContentHandler& cts) - : contentHandler(), m_contentType(cts.m_contentType), m_encoding(cts.m_encoding), - m_stream(cts.m_stream), m_length(cts.m_length) -{ + : contentHandler(), + m_contentType(cts.m_contentType), + m_encoding(cts.m_encoding), + m_stream(cts.m_stream), + m_length(cts.m_length) { + } -shared_ptr streamContentHandler::clone() const -{ +shared_ptr streamContentHandler::clone() const { + return make_shared (*this); } -streamContentHandler& streamContentHandler::operator=(const streamContentHandler& cts) -{ +streamContentHandler& streamContentHandler::operator=(const streamContentHandler& cts) { + m_contentType = cts.m_contentType; m_encoding = cts.m_encoding; m_stream = cts.m_stream; m_length = cts.m_length; - return (*this); + return *this; } -void streamContentHandler::setData(const shared_ptr & is, - const size_t length, const vmime::encoding& enc) -{ +void streamContentHandler::setData( + const shared_ptr & is, + const size_t length, + const vmime::encoding& enc +) { + m_encoding = enc; m_length = length; m_stream = is; } -void streamContentHandler::generate(utility::outputStream& os, const vmime::encoding& enc, - const size_t maxLineLength) const -{ - if (!m_stream) +void streamContentHandler::generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength +) const { + + if (!m_stream) { return; + } // Managed data is already encoded - if (isEncoded()) - { + if (isEncoded()) { + // The data is already encoded but the encoding specified for // the generation is different from the current one. We need // to re-encode data: decode from input buffer to temporary // buffer, and then re-encode to output stream... - if (m_encoding != enc) - { + if (m_encoding != enc) { + shared_ptr theDecoder = m_encoding.getEncoder(); shared_ptr theEncoder = enc.getEncoder(); @@ -117,18 +131,18 @@ void streamContentHandler::generate(utility::outputStream& os, const vmime::enco utility::inputStreamStringAdapter tempIn(str); theEncoder->encode(tempIn, os); - } + // No encoding to perform - else - { + } else { + m_stream->reset(); // may not work... utility::bufferedStreamCopy(*m_stream, os); } - } + // Need to encode data before - else - { + } else { + shared_ptr theEncoder = enc.getEncoder(); theEncoder->getProperties()["maxlinelength"] = maxLineLength; theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT); @@ -140,25 +154,29 @@ void streamContentHandler::generate(utility::outputStream& os, const vmime::enco } -void streamContentHandler::extract(utility::outputStream& os, - utility::progressListener* progress) const -{ - if (!m_stream) +void streamContentHandler::extract( + utility::outputStream& os, + utility::progressListener* progress +) const { + + if (!m_stream) { return; + } // No decoding to perform - if (!isEncoded()) - { + if (!isEncoded()) { + m_stream->reset(); // may not work... - if (progress) + if (progress) { utility::bufferedStreamCopy(*m_stream, os, getLength(), progress); - else + } else { utility::bufferedStreamCopy(*m_stream, os); - } + } + // Need to decode data - else - { + } else { + shared_ptr theDecoder = m_encoding.getEncoder(); m_stream->reset(); // may not work... @@ -170,63 +188,68 @@ void streamContentHandler::extract(utility::outputStream& os, } -void streamContentHandler::extractRaw(utility::outputStream& os, - utility::progressListener* progress) const -{ - if (!m_stream) +void streamContentHandler::extractRaw( + utility::outputStream& os, + utility::progressListener* progress +) const { + + if (!m_stream) { return; + } m_stream->reset(); // may not work... - if (progress) + if (progress) { utility::bufferedStreamCopy(*m_stream, os, getLength(), progress); - else + } else { utility::bufferedStreamCopy(*m_stream, os); + } } -size_t streamContentHandler::getLength() const -{ - return (m_length); +size_t streamContentHandler::getLength() const { + + return m_length; } -bool streamContentHandler::isEmpty() const -{ - return (m_length == 0 || !m_stream); +bool streamContentHandler::isEmpty() const { + + return m_length == 0 || !m_stream; } -bool streamContentHandler::isEncoded() const -{ - return (m_encoding != NO_ENCODING); +bool streamContentHandler::isEncoded() const { + + return m_encoding != NO_ENCODING; } -const vmime::encoding& streamContentHandler::getEncoding() const -{ - return (m_encoding); +const vmime::encoding& streamContentHandler::getEncoding() const { + + return m_encoding; } -bool streamContentHandler::isBuffered() const -{ - if (dynamicCast (m_stream) != NULL) +bool streamContentHandler::isBuffered() const { + + if (dynamicCast (m_stream)) { return true; + } // FIXME: some streams can be resetted return false; } -void streamContentHandler::setContentTypeHint(const mediaType& type) -{ +void streamContentHandler::setContentTypeHint(const mediaType& type) { + m_contentType = type; } -const mediaType streamContentHandler::getContentTypeHint() const -{ +const mediaType streamContentHandler::getContentTypeHint() const { + return m_contentType; } diff --git a/src/vmime/streamContentHandler.hpp b/src/vmime/streamContentHandler.hpp index db1e8052..6964a1c1 100644 --- a/src/vmime/streamContentHandler.hpp +++ b/src/vmime/streamContentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,15 +28,13 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { /** A content handler which obtains its data from a stream. */ +class VMIME_EXPORT streamContentHandler : public contentHandler { -class VMIME_EXPORT streamContentHandler : public contentHandler -{ public: /** Creates a new empty content handler. No data can be extracted until @@ -57,10 +55,11 @@ public: * * @return a reference to a new content handler */ - streamContentHandler - (const shared_ptr & is, - const size_t length, - const vmime::encoding& enc = NO_ENCODING); + streamContentHandler( + const shared_ptr & is, + const size_t length, + const vmime::encoding& enc = NO_ENCODING + ); ~streamContentHandler(); @@ -78,13 +77,18 @@ public: * @param enc set to anything other than NO_ENCODING if the data obtained * from the stream is already encoded with the specified encoding */ - void setData - (const shared_ptr & is, - const size_t length, - const vmime::encoding& enc = NO_ENCODING); + void setData( + const shared_ptr & is, + const size_t length, + const vmime::encoding& enc = NO_ENCODING + ); - void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + void generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength = lineLengthLimits::infinite + ) const; void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; diff --git a/src/vmime/stringContentHandler.cpp b/src/vmime/stringContentHandler.cpp index 9a66663c..616c2f55 100644 --- a/src/vmime/stringContentHandler.cpp +++ b/src/vmime/stringContentHandler.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,103 +28,126 @@ #include "vmime/utility/outputStreamAdapter.hpp" -namespace vmime -{ +namespace vmime { -stringContentHandler::stringContentHandler() -{ +stringContentHandler::stringContentHandler() { + } -stringContentHandler::stringContentHandler(const string& buffer, const vmime::encoding& enc) - : m_encoding(enc), m_string(buffer) -{ +stringContentHandler::stringContentHandler( + const string& buffer, + const vmime::encoding& enc +) + : m_encoding(enc), + m_string(buffer) { + } -stringContentHandler::stringContentHandler(const stringContentHandler& cts) - : contentHandler(), m_contentType(cts.m_contentType), - m_encoding(cts.m_encoding), m_string(cts.m_string) -{ +stringContentHandler::stringContentHandler( + const stringContentHandler& cts +) + : contentHandler(), + m_contentType(cts.m_contentType), + m_encoding(cts.m_encoding), + m_string(cts.m_string) { + } -stringContentHandler::stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc) - : m_encoding(enc), m_string(str) -{ +stringContentHandler::stringContentHandler( + const utility::stringProxy& str, + const vmime::encoding& enc +) + : m_encoding(enc), + m_string(str) { + } -stringContentHandler::stringContentHandler(const string& buffer, const size_t start, - const size_t end, const vmime::encoding& enc) - : m_encoding(enc), m_string(buffer, start, end) -{ +stringContentHandler::stringContentHandler( + const string& buffer, + const size_t start, + const size_t end, + const vmime::encoding& enc +) + : m_encoding(enc), + m_string(buffer, start, end) { + } -stringContentHandler::~stringContentHandler() -{ +stringContentHandler::~stringContentHandler() { + } -shared_ptr stringContentHandler::clone() const -{ +shared_ptr stringContentHandler::clone() const { + return make_shared (*this); } -stringContentHandler& stringContentHandler::operator=(const stringContentHandler& cts) -{ +stringContentHandler& stringContentHandler::operator=(const stringContentHandler& cts) { + m_contentType = cts.m_contentType; m_encoding = cts.m_encoding; m_string = cts.m_string; - return (*this); + return *this; } -void stringContentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc) -{ +void stringContentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc) { + m_encoding = enc; m_string = str; } -void stringContentHandler::setData(const string& buffer, const vmime::encoding& enc) -{ +void stringContentHandler::setData(const string& buffer, const vmime::encoding& enc) { + m_encoding = enc; m_string.set(buffer); } -void stringContentHandler::setData(const string& buffer, const size_t start, - const size_t end, const vmime::encoding& enc) -{ +void stringContentHandler::setData( + const string& buffer, + const size_t start, + const size_t end, + const vmime::encoding& enc +) { + m_encoding = enc; m_string.set(buffer, start, end); } -stringContentHandler& stringContentHandler::operator=(const string& buffer) -{ +stringContentHandler& stringContentHandler::operator=(const string& buffer) { + setData(buffer, NO_ENCODING); - return (*this); + return *this; } -void stringContentHandler::generate(utility::outputStream& os, - const vmime::encoding& enc, const size_t maxLineLength) const -{ +void stringContentHandler::generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength +) const { + // Managed data is already encoded - if (isEncoded()) - { + if (isEncoded()) { + // The data is already encoded but the encoding specified for // the generation is different from the current one. We need // to re-encode data: decode from input buffer to temporary // buffer, and then re-encode to output stream... - if (m_encoding != enc) - { + if (m_encoding != enc) { + shared_ptr theDecoder = m_encoding.getEncoder(); shared_ptr theEncoder = enc.getEncoder(); @@ -142,16 +165,16 @@ void stringContentHandler::generate(utility::outputStream& os, utility::inputStreamStringAdapter tempIn(str); theEncoder->encode(tempIn, os); - } + // No encoding to perform - else - { + } else { + m_string.extract(os); } - } + // Need to encode data before - else - { + } else { + shared_ptr theEncoder = enc.getEncoder(); theEncoder->getProperties()["maxlinelength"] = maxLineLength; theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT); @@ -163,17 +186,19 @@ void stringContentHandler::generate(utility::outputStream& os, } -void stringContentHandler::extract(utility::outputStream& os, - utility::progressListener* progress) const -{ +void stringContentHandler::extract( + utility::outputStream& os, + utility::progressListener* progress +) const { + // No decoding to perform - if (!isEncoded()) - { + if (!isEncoded()) { + m_string.extract(os, 0, m_string.length(), progress); - } + // Need to decode data - else - { + } else { + shared_ptr theDecoder = m_encoding.getEncoder(); utility::inputStreamStringProxyAdapter in(m_string); @@ -184,51 +209,53 @@ void stringContentHandler::extract(utility::outputStream& os, } -void stringContentHandler::extractRaw(utility::outputStream& os, - utility::progressListener* progress) const -{ +void stringContentHandler::extractRaw( + utility::outputStream& os, + utility::progressListener* progress +) const { + m_string.extract(os, 0, m_string.length(), progress); } -size_t stringContentHandler::getLength() const -{ - return (m_string.length()); +size_t stringContentHandler::getLength() const { + + return m_string.length(); } -bool stringContentHandler::isEmpty() const -{ - return (m_string.length() == 0); +bool stringContentHandler::isEmpty() const { + + return m_string.length() == 0; } -bool stringContentHandler::isEncoded() const -{ - return (m_encoding != NO_ENCODING); +bool stringContentHandler::isEncoded() const { + + return m_encoding != NO_ENCODING; } -const vmime::encoding& stringContentHandler::getEncoding() const -{ - return (m_encoding); +const vmime::encoding& stringContentHandler::getEncoding() const { + + return m_encoding; } -bool stringContentHandler::isBuffered() const -{ +bool stringContentHandler::isBuffered() const { + return true; } -void stringContentHandler::setContentTypeHint(const mediaType& type) -{ +void stringContentHandler::setContentTypeHint(const mediaType& type) { + m_contentType = type; } -const mediaType stringContentHandler::getContentTypeHint() const -{ +const mediaType stringContentHandler::getContentTypeHint() const { + return m_contentType; } diff --git a/src/vmime/stringContentHandler.hpp b/src/vmime/stringContentHandler.hpp index e9d34405..1a1bd1e9 100644 --- a/src/vmime/stringContentHandler.hpp +++ b/src/vmime/stringContentHandler.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,8 +28,7 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { class VMIME_EXPORT stringContentHandler : public contentHandler @@ -37,9 +36,23 @@ class VMIME_EXPORT stringContentHandler : public contentHandler public: stringContentHandler(); - stringContentHandler(const string& buffer, const vmime::encoding& enc = NO_ENCODING); - stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING); - stringContentHandler(const string& buffer, const size_t start, const size_t end, const vmime::encoding& enc = NO_ENCODING); + + stringContentHandler( + const string& buffer, + const vmime::encoding& enc = NO_ENCODING + ); + + stringContentHandler( + const utility::stringProxy& str, + const vmime::encoding& enc = NO_ENCODING + ); + + stringContentHandler( + const string& buffer, + const size_t start, + const size_t end, + const vmime::encoding& enc = NO_ENCODING + ); ~stringContentHandler(); @@ -58,13 +71,30 @@ public: // encoding/decoding will be performed on generate()/extract()). Note that the // data may be re-encoded (that is, decoded and encoded) if the encoding passed // to generate() is different from this one... - void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING); - void setData(const string& buffer, const vmime::encoding& enc = NO_ENCODING); - void setData(const string& buffer, const size_t start, const size_t end, const vmime::encoding& enc = NO_ENCODING); + void setData( + const utility::stringProxy& str, + const vmime::encoding& enc = NO_ENCODING + ); + + void setData( + const string& buffer, + const vmime::encoding& enc = NO_ENCODING + ); + + void setData( + const string& buffer, + const size_t start, + const size_t end, + const vmime::encoding& enc = NO_ENCODING + ); stringContentHandler& operator=(const string& buffer); - void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + void generate( + utility::outputStream& os, + const vmime::encoding& enc, + const size_t maxLineLength = lineLengthLimits::infinite + ) const; void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; diff --git a/src/vmime/text.cpp b/src/vmime/text.cpp index 28fda3ad..86ba44f1 100644 --- a/src/vmime/text.cpp +++ b/src/vmime/text.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -27,220 +27,238 @@ #include "vmime/encoding.hpp" -namespace vmime -{ +namespace vmime { -text::text() -{ +text::text() { + } text::text(const text& t) - : headerFieldValue() -{ + : headerFieldValue() { + copyFrom(t); } -text::text(const string& t, const charset& ch) -{ +text::text(const string& t, const charset& ch) { + createFromString(t, ch); } -text::text(const string& t) -{ +text::text(const string& t) { + createFromString(t, charset::getLocalCharset()); } -text::text(const word& w) -{ +text::text(const word& w) { + appendWord(make_shared (w)); } -text::~text() -{ +text::~text() { + removeAllWords(); } -void text::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void text::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + removeAllWords(); size_t newPos; - const std::vector > words = word::parseMultiple(ctx, buffer, position, end, &newPos); + const std::vector > words = + word::parseMultiple(ctx, buffer, position, end, &newPos); copy_vector(words, m_words); setParsedBounds(position, newPos); - if (newPosition) + if (newPosition) { *newPosition = newPos; + } } -void text::generateImpl - (const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void text::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + encodeAndFold(ctx, os, curLinePos, newLinePos, 0); } -void text::copyFrom(const component& other) -{ +void text::copyFrom(const component& other) { + const text& t = dynamic_cast (other); removeAllWords(); - for (std::vector >::const_iterator i = t.m_words.begin() ; i != t.m_words.end() ; ++i) + for (std::vector >::const_iterator i = t.m_words.begin() ; + i != t.m_words.end() ; ++i) { + m_words.push_back(make_shared (**i)); + } } -text& text::operator=(const component& other) -{ +text& text::operator=(const component& other) { + copyFrom(other); - return (*this); + return *this; } -text& text::operator=(const text& other) -{ +text& text::operator=(const text& other) { + copyFrom(other); - return (*this); + return *this; } -bool text::operator==(const text& t) const -{ - if (getWordCount() == t.getWordCount()) - { +bool text::operator==(const text& t) const { + + if (getWordCount() == t.getWordCount()) { + bool equal = true; std::vector >::const_iterator i = m_words.begin(); std::vector >::const_iterator j = t.m_words.begin(); - for ( ; equal && i != m_words.end() ; ++i, ++j) + for ( ; equal && i != m_words.end() ; ++i, ++j) { equal = (**i == **j); + } - return (equal); + return equal; } - return (false); + return false; } -bool text::operator!=(const text& t) const -{ +bool text::operator!=(const text& t) const { + return !(*this == t); } -const string text::getConvertedText(const charset& dest, const charsetConverterOptions& opts) const -{ +const string text::getConvertedText( + const charset& dest, + const charsetConverterOptions& opts +) const { + string out; - for (std::vector >::const_iterator i = m_words.begin() ; i != m_words.end() ; ++i) - out += (*i)->getConvertedText(dest, opts); + for (std::vector >::const_iterator i = m_words.begin() ; + i != m_words.end() ; ++i) { - return (out); + out += (*i)->getConvertedText(dest, opts); + } + + return out; } -void text::appendWord(const shared_ptr & w) -{ +void text::appendWord(const shared_ptr & w) { + m_words.push_back(w); } -void text::insertWordBefore(const size_t pos, const shared_ptr & w) -{ +void text::insertWordBefore(const size_t pos, const shared_ptr & w) { + m_words.insert(m_words.begin() + pos, w); } -void text::insertWordAfter(const size_t pos, const shared_ptr & w) -{ +void text::insertWordAfter(const size_t pos, const shared_ptr & w) { + m_words.insert(m_words.begin() + pos + 1, w); } -void text::removeWord(const size_t pos) -{ +void text::removeWord(const size_t pos) { + const std::vector >::iterator it = m_words.begin() + pos; m_words.erase(it); } -void text::removeAllWords() -{ +void text::removeAllWords() { + m_words.clear(); } -size_t text::getWordCount() const -{ - return (m_words.size()); +size_t text::getWordCount() const { + + return m_words.size(); } -bool text::isEmpty() const -{ - return (m_words.empty()); +bool text::isEmpty() const { + + return m_words.empty(); } -const shared_ptr text::getWordAt(const size_t pos) -{ - return (m_words[pos]); +const shared_ptr text::getWordAt(const size_t pos) { + + return m_words[pos]; } -const shared_ptr text::getWordAt(const size_t pos) const -{ - return (m_words[pos]); +const shared_ptr text::getWordAt(const size_t pos) const { + + return m_words[pos]; } -const std::vector > text::getWordList() const -{ +const std::vector > text::getWordList() const { + std::vector > list; list.reserve(m_words.size()); for (std::vector >::const_iterator it = m_words.begin() ; - it != m_words.end() ; ++it) - { + it != m_words.end() ; ++it) { + list.push_back(*it); } - return (list); + return list; } -const std::vector > text::getWordList() -{ - return (m_words); +const std::vector > text::getWordList() { + + return m_words; } -shared_ptr text::clone() const -{ +shared_ptr text::clone() const { + return make_shared (*this); } -shared_ptr text::newFromString(const string& in, const charset& ch) -{ +shared_ptr text::newFromString(const string& in, const charset& ch) { + shared_ptr t = make_shared (); t->createFromString(in, ch); @@ -249,8 +267,8 @@ shared_ptr text::newFromString(const string& in, const charset& ch) } -void text::createFromString(const string& in, const charset& ch) -{ +void text::createFromString(const string& in, const charset& ch) { + size_t asciiCount = 0; size_t asciiPercent = 0; @@ -263,46 +281,45 @@ void text::createFromString(const string& in, const charset& ch) encoding recommendedEnc; const bool alwaysEncode = ch.getRecommendedEncoding(recommendedEnc); - if (!alwaysEncode) - { + if (!alwaysEncode) { asciiCount = utility::stringUtils::countASCIIchars(in.begin(), in.end()); asciiPercent = (in.length() == 0 ? 100 : (100 * asciiCount) / in.length()); } // If there are "too much" non-ASCII chars, encode everything - if (alwaysEncode || asciiPercent < 60) // less than 60% ASCII chars - { + if (alwaysEncode || asciiPercent < 60) { // less than 60% ASCII chars + appendWord(make_shared (in, ch)); - } + // Else, only encode words which need it - else - { + } else { + bool is8bit = false; // is the current word 8-bit? bool prevIs8bit = false; // is previous word 8-bit? unsigned int count = 0; // total number of words - for (size_t end = in.size(), pos = 0, start = 0 ; ; ) - { - if (pos == end || parserHelpers::isSpace(in[pos])) - { + for (size_t end = in.size(), pos = 0, start = 0 ; ; ) { + + if (pos == end || parserHelpers::isSpace(in[pos])) { + const string chunk(in.begin() + start, in.begin() + pos); - if (pos != end) + if (pos != end) { ++pos; + } + + if (is8bit) { + + if (count && prevIs8bit) { - if (is8bit) - { - if (count && prevIs8bit) - { // No need to create a new encoded word, just append // the current word to the previous one. shared_ptr w = getWordAt(getWordCount() - 1); w->getBuffer() += " " + chunk; - } - else - { - if (count) - { + + } else { + + if (count) { shared_ptr w = getWordAt(getWordCount() - 1); w->getBuffer() += ' '; } @@ -312,37 +329,37 @@ void text::createFromString(const string& in, const charset& ch) prevIs8bit = true; ++count; } - } - else - { - if (count && !prevIs8bit) - { + + } else { + + if (count && !prevIs8bit) { + shared_ptr w = getWordAt(getWordCount() - 1); w->getBuffer() += " " + chunk; - } - else - { - appendWord(make_shared - (chunk, charset(charsets::US_ASCII))); + + } else { + + appendWord(make_shared (chunk, charset(charsets::US_ASCII))); prevIs8bit = false; ++count; } } - if (pos == end) + if (pos == end) { break; + } is8bit = false; start = pos; - } - else if (!parserHelpers::isAscii(in[pos])) - { + + } else if (!parserHelpers::isAscii(in[pos])) { + is8bit = true; ++pos; - } - else - { + + } else { + ++pos; } } @@ -350,26 +367,33 @@ void text::createFromString(const string& in, const charset& ch) } -void text::encodeAndFold - (const generationContext& ctx, utility::outputStream& os, - const size_t firstLineOffset, size_t* lastLineLength, const int flags) const -{ +void text::encodeAndFold( + const generationContext& ctx, + utility::outputStream& os, + const size_t firstLineOffset, + size_t* lastLineLength, + const int flags +) const { + size_t curLineLength = firstLineOffset; word::generatorState state; - for (size_t wi = 0 ; wi < getWordCount() ; ++wi) - { - getWordAt(wi)->generate(ctx, os, curLineLength, - &curLineLength, flags, &state); + for (size_t wi = 0 ; wi < getWordCount() ; ++wi) { + + getWordAt(wi)->generate( + ctx, os, curLineLength, + &curLineLength, flags, &state + ); } - if (lastLineLength) + if (lastLineLength) { *lastLineLength = curLineLength; + } } -shared_ptr text::decodeAndUnfold(const string& in) -{ +shared_ptr text::decodeAndUnfold(const string& in) { + shared_ptr t = make_shared (); decodeAndUnfold(parsingContext::getDefaultContext(), in, t.get()); @@ -378,8 +402,8 @@ shared_ptr text::decodeAndUnfold(const string& in) } -shared_ptr text::decodeAndUnfold(const parsingContext& ctx, const string& in) -{ +shared_ptr text::decodeAndUnfold(const parsingContext& ctx, const string& in) { + shared_ptr t = make_shared (); decodeAndUnfold(ctx, in, t.get()); @@ -388,15 +412,15 @@ shared_ptr text::decodeAndUnfold(const parsingContext& ctx, const string& } -text* text::decodeAndUnfold(const string& in, text* generateInExisting) -{ +text* text::decodeAndUnfold(const string& in, text* generateInExisting) { + return decodeAndUnfold(parsingContext::getDefaultContext(), in, generateInExisting); } -text* text::decodeAndUnfold(const parsingContext& ctx, const string& in, text* generateInExisting) -{ - text* out = (generateInExisting != NULL) ? generateInExisting : new text(); +text* text::decodeAndUnfold(const parsingContext& ctx, const string& in, text* generateInExisting) { + + text* out = generateInExisting ? generateInExisting : new text(); out->removeAllWords(); @@ -405,55 +429,56 @@ text* text::decodeAndUnfold(const parsingContext& ctx, const string& in, text* g copy_vector(words, out->m_words); - return (out); + return out; } // static -void text::fixBrokenWords(std::vector >& words) -{ - if (words.size() < 2) +void text::fixBrokenWords(std::vector >& words) { + + if (words.size() < 2) { return; + } // Fix words which encode a non-integral number of characters. // This is not RFC-compliant, but we should be able to recover from it. - for (size_t i = 0, n = words.size() ; i < n - 1 ; ++i) - { + for (size_t i = 0, n = words.size() ; i < n - 1 ; ++i) { + shared_ptr w1 = words[i]; // Check whether the word is valid bool valid = false; - try - { + try { + valid = w1->getCharset().isValidText(w1->getBuffer(), NULL); - } - catch (vmime::exceptions::charset_conv_error& e) - { + + } catch (vmime::exceptions::charset_conv_error& e) { + // Unknown charset or unexpected conversion error: assume word is valid valid = true; } // If the current word is not valid, try to grab some bytes // from the next words, to see whether it becomes valid. - if (!valid) - { + if (!valid) { + string buffer(w1->getBuffer()); size_t mergeWords = 1; // number of adjacent words to merge - for (size_t j = i + 1 ; j < n ; ++j) - { + for (size_t j = i + 1 ; j < n ; ++j) { + shared_ptr nextWord = words[j]; - if (nextWord->getCharset() != w1->getCharset()) + if (nextWord->getCharset() != w1->getCharset()) { break; + } buffer += nextWord->getBuffer(); ++mergeWords; } - if (mergeWords == 1) - { + if (mergeWords == 1) { // No adjacent word with same charset found continue; } @@ -467,15 +492,15 @@ void text::fixBrokenWords(std::vector >& words) words[i + 1]->setBuffer(string(buffer.begin() + firstInvalidByte, buffer.end())); // Remove unused words - for (size_t j = 0 ; j < mergeWords - 2 ; ++j) - { + for (size_t j = 0 ; j < mergeWords - 2 ; ++j) { + words.erase(words.begin() + i + 2); --n; } // If the next word is now empty, remove it - if (words[i + 1]->getBuffer().empty()) - { + if (words[i + 1]->getBuffer().empty()) { + words.erase(words.begin() + i + 1); --n; } @@ -484,23 +509,23 @@ void text::fixBrokenWords(std::vector >& words) } -const std::vector > text::getChildComponents() -{ +const std::vector > text::getChildComponents() { + std::vector > list; copy_vector(m_words, list); - return (list); + return list; } -const string text::getWholeBuffer() const -{ +const string text::getWholeBuffer() const { + string res; for (std::vector >::const_iterator it = m_words.begin() ; - it != m_words.end() ; ++it) - { + it != m_words.end() ; ++it) { + res += (*it)->getBuffer(); } diff --git a/src/vmime/text.hpp b/src/vmime/text.hpp index b11454cb..143f5270 100644 --- a/src/vmime/text.hpp +++ b/src/vmime/text.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,15 +30,13 @@ #include "vmime/word.hpp" -namespace vmime -{ +namespace vmime { /** List of encoded-words, as defined in RFC-2047 (basic type). */ +class VMIME_EXPORT text : public headerFieldValue { -class VMIME_EXPORT text : public headerFieldValue -{ public: text(); @@ -138,8 +136,10 @@ public: * @param opts options for charset conversion * @return text decoded in the specified charset */ - const string getConvertedText(const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()) const; + const string getConvertedText( + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ) const; /** Return the unconverted (raw) data of all words. This is the * concatenation of the results returned by getBuffer() on @@ -188,8 +188,8 @@ public: /** Flags used by "encodeAndFold" function. */ - enum EncodeAndFoldFlags - { + enum EncodeAndFoldFlags { + // NOTE: If both "FORCE_NO_ENCODING" and "FORCE_ENCODING" are // specified, "FORCE_NO_ENCODING" is used by default. @@ -208,8 +208,13 @@ public: * @param lastLineLength will receive the length of the last line written * @param flags encoding flags (see EncodeAndFoldFlags) */ - void encodeAndFold(const generationContext& ctx, utility::outputStream& os, - const size_t firstLineOffset, size_t* lastLineLength, const int flags) const; + void encodeAndFold( + const generationContext& ctx, + utility::outputStream& os, + const size_t firstLineOffset, + size_t* lastLineLength, + const int flags + ) const; /** Decode and unfold text (RFC-2047), using the default parsing context. * @@ -247,7 +252,11 @@ public: * resulting object into an existing object. * @return new text object or existing object if generateInExisting != NULL */ - static text* decodeAndUnfold(const parsingContext& ctx, const string& in, text* generateInExisting); + static text* decodeAndUnfold( + const parsingContext& ctx, + const string& in, + text* generateInExisting + ); protected: @@ -255,18 +264,20 @@ protected: // Component parsing & assembling - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; private: diff --git a/src/vmime/textPart.hpp b/src/vmime/textPart.hpp index 4be0535d..e34a169a 100644 --- a/src/vmime/textPart.hpp +++ b/src/vmime/textPart.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,15 +32,13 @@ #include "vmime/contentHandler.hpp" -namespace vmime -{ +namespace vmime { /** Generic text part. */ +class VMIME_EXPORT textPart : public object { -class VMIME_EXPORT textPart : public object -{ friend class textPartFactory; friend class messageBuilder; // for generateIn, getPartCount friend class messageParser; // for parse @@ -94,7 +92,10 @@ public: * @param message the message * @param parent body part into which generate this part */ - virtual void generateIn(const shared_ptr & message, const shared_ptr & parent) const = 0; + virtual void generateIn( + const shared_ptr & message, + const shared_ptr & parent + ) const = 0; /** Parse the text part(s) from the specified message. * @@ -102,7 +103,11 @@ public: * @param parent part containing the text part * @param textPart actual text part */ - virtual void parse(const shared_ptr & message, const shared_ptr & parent, const shared_ptr & textPart) = 0; + virtual void parse( + const shared_ptr & message, + const shared_ptr & parent, + const shared_ptr & textPart + ) = 0; }; diff --git a/src/vmime/textPartFactory.cpp b/src/vmime/textPartFactory.cpp index 846a6605..2c58888a 100644 --- a/src/vmime/textPartFactory.cpp +++ b/src/vmime/textPartFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,37 +29,36 @@ #include "vmime/htmlTextPart.hpp" -namespace vmime -{ +namespace vmime { -textPartFactory::textPartFactory() -{ - // Register some default names +textPartFactory::textPartFactory() { + registerType (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); registerType (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML)); } -textPartFactory::~textPartFactory() -{ +textPartFactory::~textPartFactory() { + } -textPartFactory* textPartFactory::getInstance() -{ +textPartFactory* textPartFactory::getInstance() { + static textPartFactory instance; - return (&instance); + return &instance; } shared_ptr textPartFactory::create(const mediaType& type) { for (MapType::const_iterator it = m_map.begin() ; - it != m_map.end() ; ++it) - { - if ((*it).first == type) + it != m_map.end() ; ++it) { + + if ((*it).first == type) { return ((*it).second)(); + } } throw exceptions::no_factory_available("No 'textPart' class registered for media type '" + type.generate() + "'."); diff --git a/src/vmime/textPartFactory.hpp b/src/vmime/textPartFactory.hpp index f5ce3774..322c6161 100644 --- a/src/vmime/textPartFactory.hpp +++ b/src/vmime/textPartFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,12 +29,11 @@ #include "vmime/mediaType.hpp" -namespace vmime -{ +namespace vmime { -class VMIME_EXPORT textPartFactory -{ +class VMIME_EXPORT textPartFactory { + protected: textPartFactory(); @@ -47,12 +46,11 @@ protected: #ifndef VMIME_BUILDING_DOC template - class registerer - { + class registerer { public: - static shared_ptr creator() - { + static shared_ptr creator() { + // Allocate a new object return vmime::make_shared (); } @@ -64,8 +62,8 @@ public: static textPartFactory* getInstance(); template - void registerType(const mediaType& type) - { + void registerType(const mediaType& type) { + m_map.push_back(MapType::value_type(type, ®isterer::creator)); } diff --git a/src/vmime/types.hpp b/src/vmime/types.hpp index 7f2a0354..35278838 100644 --- a/src/vmime/types.hpp +++ b/src/vmime/types.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,8 +38,8 @@ #ifndef VMIME_BUILDING_DOC -namespace vmime -{ +namespace vmime { + using std::shared_ptr; using std::weak_ptr; using std::make_shared; @@ -52,8 +52,7 @@ namespace vmime * only for the singleton classes allocated on the stack. */ template - struct noop_shared_ptr_deleter - { + struct noop_shared_ptr_deleter { void operator()(T*) const {} }; @@ -63,8 +62,8 @@ namespace vmime #endif // VMIME_BUILDING_DOC -namespace vmime -{ +namespace vmime { + typedef std::string string; typedef unsigned short port_t; diff --git a/src/vmime/utility/childProcess.hpp b/src/vmime/utility/childProcess.hpp index 4898e3f7..b72ab850 100644 --- a/src/vmime/utility/childProcess.hpp +++ b/src/vmime/utility/childProcess.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,16 +38,14 @@ namespace utility { /** Spawn a process and redirect its standard input * and/or standard output. */ +class VMIME_EXPORT childProcess : public object { -class VMIME_EXPORT childProcess : public object -{ public: virtual ~childProcess() { } /** Flags used with start(). */ - enum Flags - { + enum Flags { FLAG_REDIRECT_STDIN = (1 << 0), FLAG_REDIRECT_STDOUT = (1 << 1) }; @@ -84,9 +82,8 @@ public: /** Create 'childProcess' objects. */ +class childProcessFactory : public object { -class childProcessFactory : public object -{ public: virtual ~childProcessFactory() { } @@ -104,4 +101,3 @@ public: #endif // VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED - diff --git a/src/vmime/utility/datetimeUtils.cpp b/src/vmime/utility/datetimeUtils.cpp index 2b55177e..b1a6c552 100644 --- a/src/vmime/utility/datetimeUtils.cpp +++ b/src/vmime/utility/datetimeUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,130 +32,103 @@ namespace utility { #ifndef VMIME_BUILDING_DOC -static inline void nextMonth(datetime& d) -{ - if (d.getMonth() >= 12) - { +static inline void nextMonth(datetime& d) { + + if (d.getMonth() >= 12) { d.setMonth(1); d.setYear(d.getYear() + 1); - } - else - { + } else { d.setMonth(d.getMonth() + 1); } } -static inline void prevMonth(datetime& d) -{ - if (d.getMonth() <= 1) - { +static inline void prevMonth(datetime& d) { + + if (d.getMonth() <= 1) { d.setYear(d.getYear() - 1); d.setMonth(12); - } - else - { + } else { d.setMonth(d.getMonth() - 1); } } -static inline void nextDay(datetime& d) -{ +static inline void nextDay(datetime& d) { - if (d.getDay() >= datetimeUtils::getDaysInMonth(d.getYear(), d.getMonth())) - { + if (d.getDay() >= datetimeUtils::getDaysInMonth(d.getYear(), d.getMonth())) { d.setDay(1); nextMonth(d); - } - else - { + } else { d.setDay(d.getDay() + 1); } } -static inline void prevDay(datetime& d) -{ - if (d.getDay() <= 1) - { +static inline void prevDay(datetime& d) { + + if (d.getDay() <= 1) { prevMonth(d); d.setDay(datetimeUtils::getDaysInMonth(d.getYear(), d.getMonth())); - } - else - { + } else { d.setDay(d.getDay() - 1); } } -static inline void nextHour(datetime& d) -{ - if (d.getHour() >= 23) - { +static inline void nextHour(datetime& d) { + + if (d.getHour() >= 23) { d.setHour(0); nextDay(d); - } - else - { + } else { d.setHour(d.getHour() + 1); } } -static inline void prevHour(datetime& d) -{ - if (d.getHour() <= 0) - { +static inline void prevHour(datetime& d) { + + if (d.getHour() <= 0) { d.setHour(23); prevDay(d); - } - else - { + } else { d.setHour(d.getHour() - 1); } } -static inline void addHoursAndMinutes(datetime& d, const int h, const int m) -{ +static inline void addHoursAndMinutes(datetime& d, const int h, const int m) { + d.setMinute(d.getMinute() + m); - if (d.getMinute() >= 60) - { + if (d.getMinute() >= 60) { d.setMinute(d.getMinute() - 60); nextHour(d); } d.setHour(d.getHour() + h); - if (d.getHour() >= 24) - { + if (d.getHour() >= 24) { d.setHour(d.getHour() - 24); nextDay(d); } } -static inline void substractHoursAndMinutes(datetime& d, const int h, const int m) -{ - if (m > d.getMinute()) - { +static inline void substractHoursAndMinutes(datetime& d, const int h, const int m) { + + if (m > d.getMinute()) { d.setMinute(60 - (m - d.getMinute())); prevHour(d); - } - else - { + } else { d.setMinute(d.getMinute() - m); } - if (h > d.getHour()) - { + if (h > d.getHour()) { d.setHour(24 - (h - d.getHour())); prevDay(d); - } - else - { + } else { d.setHour(d.getHour() - h); } } @@ -163,10 +136,11 @@ static inline void substractHoursAndMinutes(datetime& d, const int h, const int #endif // VMIME_BUILDING_DOC -const datetime datetimeUtils::toUniversalTime(const datetime& date) -{ - if (date.getZone() == datetime::GMT) +const datetime datetimeUtils::toUniversalTime(const datetime& date) { + + if (date.getZone() == datetime::GMT) { return date; // no conversion needed + } datetime nd(date); nd.setZone(datetime::GMT); @@ -175,21 +149,23 @@ const datetime datetimeUtils::toUniversalTime(const datetime& date) const int h = (z < 0) ? (-z / 60) : (z / 60); const int m = (z < 0) ? (-z - h * 60) : (z - h * 60); - if (z < 0) // GMT-hhmm: add hours and minutes to date + if (z < 0) { // GMT-hhmm: add hours and minutes to date addHoursAndMinutes(nd, h, m); - else // GMT+hhmm: substract hours and minutes from date + } else { // GMT+hhmm: substract hours and minutes from date substractHoursAndMinutes(nd, h, m); + } - return (nd); + return nd; } -const datetime datetimeUtils::toLocalTime(const datetime& date, const int zone) -{ +const datetime datetimeUtils::toLocalTime(const datetime& date, const int zone) { + datetime utcDate(date); - if (utcDate.getZone() != datetime::GMT) + if (utcDate.getZone() != datetime::GMT) { utcDate = toUniversalTime(date); // convert to UT before + } datetime nd(utcDate); nd.setZone(zone); @@ -197,53 +173,57 @@ const datetime datetimeUtils::toLocalTime(const datetime& date, const int zone) const int h = (zone < 0) ? (-zone / 60) : (zone / 60); const int m = (zone < 0) ? (-zone - h * 60) : (zone - h * 60); - if (zone < 0) // GMT+hhmm: substract hours and minutes from date + if (zone < 0) { // GMT+hhmm: substract hours and minutes from date substractHoursAndMinutes(nd, h, m); - else // GMT-hhmm: add hours and minutes to date + } else { // GMT-hhmm: add hours and minutes to date addHoursAndMinutes(nd, h, m); + } - return (nd); + return nd; } -bool datetimeUtils::isLeapYear(const int year) -{ +bool datetimeUtils::isLeapYear(const int year) { + // From RFC 3339 - Appendix C. Leap Years: return ((year % 4) == 0 && (year % 100 != 0 || year % 400 == 0)); } -int datetimeUtils::getDaysInMonth(const int year, const int month) -{ - static const int daysInMonth[12] = - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - static const int daysInMonthLeapYear[12] = - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +int datetimeUtils::getDaysInMonth(const int year, const int month) { - if (month < 1 || month > 12) + static const int daysInMonth[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + static const int daysInMonthLeapYear[12] = { + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + }; + + if (month < 1 || month > 12) { throw std::out_of_range("Invalid month number"); + } - return (isLeapYear(year) ? daysInMonthLeapYear[month - 1] : daysInMonth[month - 1]); + return isLeapYear(year) ? daysInMonthLeapYear[month - 1] : daysInMonth[month - 1]; } -int datetimeUtils::getDayOfWeek(const int year, const int month, const int day) -{ +int datetimeUtils::getDayOfWeek(const int year, const int month, const int day) { + int y = year; int m = month; - if (month < 1 || month > 12) + if (month < 1 || month > 12) { throw std::out_of_range("Invalid month number"); - else if (day < 1 || day > getDaysInMonth(year, month)) + } else if (day < 1 || day > getDaysInMonth(year, month)) { throw std::out_of_range("Invalid day number"); + } // From RFC-3339 - Appendix B. Day of the Week // Adjust months so February is the last one m -= 2; - if (m < 1) - { + if (m < 1) { m += 12; --y; } @@ -252,25 +232,27 @@ int datetimeUtils::getDayOfWeek(const int year, const int month, const int day) const int cent = y / 100; y %= 100; - return (((26 * m - 2) / 10 + day + y + (y >> 2) + (cent >> 2) + 5 * cent) % 7); + return ((26 * m - 2) / 10 + day + y + (y >> 2) + (cent >> 2) + 5 * cent) % 7; } -int datetimeUtils::getWeekOfYear(const int year, const int month, const int day, const bool iso) -{ +int datetimeUtils::getWeekOfYear(const int year, const int month, const int day, const bool iso) { + // Algorithm from http://personal.ecu.edu/mccartyr/ISOwdALG.txt const bool leapYear = ((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0; const bool leapYear_1 = (((year - 1) % 4) == 0 && ((year - 1) % 100) != 0) || ((year - 1) % 400) == 0; // 4. Find the DayOfYearNumber for Y M D - static const int DAY_OF_YEAR_NUMBER_MAP[12] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + static const int DAY_OF_YEAR_NUMBER_MAP[12] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 + }; int DayOfYearNumber = day + DAY_OF_YEAR_NUMBER_MAP[month - 1]; - if (leapYear && month > 2) + if (leapYear && month > 2) { DayOfYearNumber += 1; + } // 5. Find the Jan1Weekday for Y (Monday=1, Sunday=7) const int YY = (year - 1) % 100; @@ -285,45 +267,47 @@ int datetimeUtils::getWeekOfYear(const int year, const int month, const int day, // 7. Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53 int YearNumber = 0, WeekNumber = 0; - if (DayOfYearNumber <= (8 - Jan1Weekday) && Jan1Weekday > 4) - { + if (DayOfYearNumber <= (8 - Jan1Weekday) && Jan1Weekday > 4) { + YearNumber = year - 1; - if (Jan1Weekday == 5 || (Jan1Weekday == 6 && leapYear_1)) + if (Jan1Weekday == 5 || (Jan1Weekday == 6 && leapYear_1)) { WeekNumber = 53; - else + } else { WeekNumber = 52; - } - else - { + } + + } else { + YearNumber = year; } // 8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1 - if (YearNumber == year) - { + if (YearNumber == year) { + const int I = (leapYear ? 366 : 365); - if ((I - DayOfYearNumber) < (4 - Weekday)) - { + if ((I - DayOfYearNumber) < (4 - Weekday)) { YearNumber = year + 1; WeekNumber = 1; } } // 9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 - if (YearNumber == year) - { + if (YearNumber == year) { + const int J = DayOfYearNumber + (7 - Weekday) + (Jan1Weekday - 1); WeekNumber = J / 7; - if (Jan1Weekday > 4) + if (Jan1Weekday > 4) { WeekNumber -= 1; + } } - if (!iso && (WeekNumber == 1 && month == 12)) + if (!iso && (WeekNumber == 1 && month == 12)) { WeekNumber = 53; + } return WeekNumber; } diff --git a/src/vmime/utility/datetimeUtils.hpp b/src/vmime/utility/datetimeUtils.hpp index a7291bb8..b762a6e6 100644 --- a/src/vmime/utility/datetimeUtils.hpp +++ b/src/vmime/utility/datetimeUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** Miscellaneous functions related to date/time. */ +class VMIME_EXPORT datetimeUtils { -class VMIME_EXPORT datetimeUtils -{ public: /** Test whether the specified year is a leap year. diff --git a/src/vmime/utility/encoder/b64Encoder.cpp b/src/vmime/utility/encoder/b64Encoder.cpp index ddaa62f8..ef4e581e 100644 --- a/src/vmime/utility/encoder/b64Encoder.cpp +++ b/src/vmime/utility/encoder/b64Encoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,18 +30,18 @@ namespace utility { namespace encoder { -b64Encoder::b64Encoder() -{ +b64Encoder::b64Encoder() { + } -const std::vector b64Encoder::getAvailableProperties() const -{ +const std::vector b64Encoder::getAvailableProperties() const { + std::vector list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); - return (list); + return list; } @@ -49,8 +49,7 @@ const std::vector b64Encoder::getAvailableProperties() const const unsigned char b64Encoder::sm_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; -const unsigned char b64Encoder::sm_decodeMap[256] = -{ +const unsigned char b64Encoder::sm_decodeMap[256] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x00 - 0x0f 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, // 0x10 - 0x1f 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3e,0xff,0xff,0xff,0x3f, // 0x20 - 0x2f @@ -75,9 +74,12 @@ const unsigned char b64Encoder::sm_decodeMap[256] = -size_t b64Encoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t b64Encoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const size_t propMaxLineLength = @@ -99,72 +101,77 @@ size_t b64Encoder::encode(utility::inputStream& in, size_t curCol = 0; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { + + if (bufferPos >= bufferLength) { - while (bufferPos < bufferLength || !in.eof()) - { - if (bufferPos >= bufferLength) - { bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Get 3 bytes of data int count = 0; - while (count < 3 && bufferPos < bufferLength) + while (count < 3 && bufferPos < bufferLength) { bytes[count++] = buffer[bufferPos++]; + } + + while (count < 3) { - while (count < 3) - { // There may be more data in the next chunk... - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } - while (count < 3 && bufferPos < bufferLength) + while (count < 3 && bufferPos < bufferLength) { bytes[count++] = buffer[bufferPos++]; + } } // Encode data - switch (count) - { - case 1: + switch (count) { - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[(bytes[0] & 0x03) << 4]; - output[2] = sm_alphabet[64]; // padding - output[3] = sm_alphabet[64]; // padding + case 1: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[(bytes[0] & 0x03) << 4]; + output[2] = sm_alphabet[64]; // padding + output[3] = sm_alphabet[64]; // padding - case 2: + break; - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; - output[2] = sm_alphabet[(bytes[1] & 0x0F) << 2]; - output[3] = sm_alphabet[64]; // padding + case 2: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; + output[2] = sm_alphabet[(bytes[1] & 0x0F) << 2]; + output[3] = sm_alphabet[64]; // padding - default: - case 3: + break; - output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; - output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; - output[2] = sm_alphabet[((bytes[1] & 0x0F) << 2) | ((bytes[2] & 0xC0) >> 6)]; - output[3] = sm_alphabet[(bytes[2] & 0x3F)]; + default: + case 3: - break; + output[0] = sm_alphabet[(bytes[0] & 0xFC) >> 2]; + output[1] = sm_alphabet[((bytes[0] & 0x03) << 4) | ((bytes[1] & 0xF0) >> 4)]; + output[2] = sm_alphabet[((bytes[1] & 0x0F) << 2) | ((bytes[2] & 0xC0) >> 6)]; + output[3] = sm_alphabet[(bytes[2] & 0x3F)]; + + break; } // Write encoded data to output stream @@ -174,26 +181,30 @@ size_t b64Encoder::encode(utility::inputStream& in, total += 4; curCol += 4; - if (cutLines && curCol + 2 /* \r\n */ + 4 /* next bytes */ >= maxLineLength) - { + if (cutLines && curCol + 2 /* \r\n */ + 4 /* next bytes */ >= maxLineLength) { out.write("\r\n", 2); curCol = 0; } - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t b64Encoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t b64Encoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -207,73 +218,78 @@ size_t b64Encoder::decode(utility::inputStream& in, byte_t bytes[4]; byte_t output[3]; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { - while (bufferPos < bufferLength || !in.eof()) - { bytes[0] = '='; bytes[1] = '='; bytes[2] = '='; bytes[3] = '='; // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // 4 bytes of input provide 3 bytes of output, so // get the next 4 bytes from the input stream. int count = 0; - while (count < 4 && bufferPos < bufferLength) - { + while (count < 4 && bufferPos < bufferLength) { + const byte_t c = buffer[bufferPos++]; - if (!parserHelpers::isSpace(c)) + if (!parserHelpers::isSpace(c)) { bytes[count++] = c; + } } - if (count != 4) - { - while (count < 4 && !in.eof()) - { + if (count != 4) { + + while (count < 4 && !in.eof()) { + // Data continues on the next chunk bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; - while (count < 4 && bufferPos < bufferLength) - { + while (count < 4 && bufferPos < bufferLength) { + const byte_t c = buffer[bufferPos++]; - if (!parserHelpers::isSpace(c)) + if (!parserHelpers::isSpace(c)) { bytes[count++] = c; + } } } } - if (count != 4) // input length is not a multiple of 4 bytes + if (count != 4) { // input length is not a multiple of 4 bytes break; + } // Decode the bytes byte_t c1 = bytes[0]; byte_t c2 = bytes[1]; - if (c1 == '=' || c2 == '=') // end + if (c1 == '=' || c2 == '=') { // end break; + } output[0] = static_cast ((sm_decodeMap[c1] << 2) | ((sm_decodeMap[c2] & 0x30) >> 4)); c1 = bytes[2]; - if (c1 == '=') // end - { + if (c1 == '=') { // end B64_WRITE(out, output, 1); total += 1; break; @@ -283,8 +299,7 @@ size_t b64Encoder::decode(utility::inputStream& in, c2 = bytes[3]; - if (c2 == '=') // end - { + if (c2 == '=') { // end B64_WRITE(out, output, 2); total += 2; break; @@ -296,19 +311,21 @@ size_t b64Encoder::decode(utility::inputStream& in, total += 3; inTotal += count; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t b64Encoder::getEncodedSize(const size_t n) const -{ +size_t b64Encoder::getEncodedSize(const size_t n) const { + const size_t propMaxLineLength = getProperties().getProperty ("maxlinelength", static_cast (-1)); @@ -321,8 +338,8 @@ size_t b64Encoder::getEncodedSize(const size_t n) const } -size_t b64Encoder::getDecodedSize(const size_t n) const -{ +size_t b64Encoder::getDecodedSize(const size_t n) const { + // 4 bytes of input provide 3 bytes of output return (n * 3) / 4; } diff --git a/src/vmime/utility/encoder/b64Encoder.hpp b/src/vmime/utility/encoder/b64Encoder.hpp index 2d23d9e3..c5be2c38 100644 --- a/src/vmime/utility/encoder/b64Encoder.hpp +++ b/src/vmime/utility/encoder/b64Encoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Base64 encoder. */ +class VMIME_EXPORT b64Encoder : public encoder { -class VMIME_EXPORT b64Encoder : public encoder -{ public: b64Encoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector getAvailableProperties() const; diff --git a/src/vmime/utility/encoder/binaryEncoder.cpp b/src/vmime/utility/encoder/binaryEncoder.cpp index 7d7c40d1..b30bb7bb 100644 --- a/src/vmime/utility/encoder/binaryEncoder.cpp +++ b/src/vmime/utility/encoder/binaryEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -binaryEncoder::binaryEncoder() -{ +binaryEncoder::binaryEncoder() { + } diff --git a/src/vmime/utility/encoder/binaryEncoder.hpp b/src/vmime/utility/encoder/binaryEncoder.hpp index 1c831939..331014e3 100644 --- a/src/vmime/utility/encoder/binaryEncoder.hpp +++ b/src/vmime/utility/encoder/binaryEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace encoder { /** Binary encoder. */ +class VMIME_EXPORT binaryEncoder : public noopEncoder { -class VMIME_EXPORT binaryEncoder : public noopEncoder -{ public: binaryEncoder(); diff --git a/src/vmime/utility/encoder/eightBitEncoder.cpp b/src/vmime/utility/encoder/eightBitEncoder.cpp index 4ab07f06..a9669319 100644 --- a/src/vmime/utility/encoder/eightBitEncoder.cpp +++ b/src/vmime/utility/encoder/eightBitEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -eightBitEncoder::eightBitEncoder() -{ +eightBitEncoder::eightBitEncoder() { + } diff --git a/src/vmime/utility/encoder/eightBitEncoder.hpp b/src/vmime/utility/encoder/eightBitEncoder.hpp index ee50ca95..c400f512 100644 --- a/src/vmime/utility/encoder/eightBitEncoder.hpp +++ b/src/vmime/utility/encoder/eightBitEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace encoder { /** 8-bit encoder. */ +class VMIME_EXPORT eightBitEncoder : public noopEncoder { -class VMIME_EXPORT eightBitEncoder : public noopEncoder -{ public: eightBitEncoder(); diff --git a/src/vmime/utility/encoder/encoder.cpp b/src/vmime/utility/encoder/encoder.cpp index b4b13249..634adf0d 100644 --- a/src/vmime/utility/encoder/encoder.cpp +++ b/src/vmime/utility/encoder/encoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,44 +30,44 @@ namespace utility { namespace encoder { -encoder::encoder() -{ +encoder::encoder() { + } -encoder::~encoder() -{ +encoder::~encoder() { + } -const propertySet& encoder::getProperties() const -{ - return (m_props); +const propertySet& encoder::getProperties() const { + + return m_props; } -propertySet& encoder::getProperties() -{ - return (m_props); +propertySet& encoder::getProperties() { + + return m_props; } -const propertySet& encoder::getResults() const -{ - return (m_results); +const propertySet& encoder::getResults() const { + + return m_results; } -propertySet& encoder::getResults() -{ - return (m_results); +propertySet& encoder::getResults() { + + return m_results; } -const std::vector encoder::getAvailableProperties() const -{ +const std::vector encoder::getAvailableProperties() const { + std::vector list; - return (list); + return list; } diff --git a/src/vmime/utility/encoder/encoder.hpp b/src/vmime/utility/encoder/encoder.hpp index 34cd10b7..134e813e 100644 --- a/src/vmime/utility/encoder/encoder.hpp +++ b/src/vmime/utility/encoder/encoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,9 +38,8 @@ namespace encoder { /** Encode/decode data in different encodings. */ +class VMIME_EXPORT encoder : public object { -class VMIME_EXPORT encoder : public object -{ public: encoder(); @@ -54,7 +53,11 @@ public: * want to receive progress notifications * @return number of bytes written into output stream */ - virtual size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + virtual size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ) = 0; /** Decode data. * @@ -64,7 +67,11 @@ public: * want to receive progress notifications * @return number of bytes written into output stream */ - virtual size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + virtual size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ) = 0; /** Return the properties of the encoder. * diff --git a/src/vmime/utility/encoder/encoderFactory.cpp b/src/vmime/utility/encoder/encoderFactory.cpp index 01ac7753..df655ae0 100644 --- a/src/vmime/utility/encoder/encoderFactory.cpp +++ b/src/vmime/utility/encoder/encoderFactory.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,8 @@ namespace utility { namespace encoder { -encoderFactory::encoderFactory() -{ +encoderFactory::encoderFactory() { + // Register some default encoders registerName ("base64"); registerName ("quoted-printable"); @@ -58,83 +58,88 @@ encoderFactory::encoderFactory() } -encoderFactory::~encoderFactory() -{ +encoderFactory::~encoderFactory() { + } -shared_ptr encoderFactory::getInstance() -{ +shared_ptr encoderFactory::getInstance() { + static encoderFactory instance; return shared_ptr (&instance, noop_shared_ptr_deleter ()); } -shared_ptr encoderFactory::create(const string& name) -{ - try - { - return (getEncoderByName(name)->create()); - } - catch (exceptions::no_encoder_available &) { +shared_ptr encoderFactory::create(const string& name) { - if (m_defaultEncoder) + try { + + return (getEncoderByName(name)->create()); + + } catch (exceptions::no_encoder_available &) { + + if (m_defaultEncoder) { return m_defaultEncoder; + } throw; } } -const shared_ptr encoderFactory::getEncoderByName(const string& name) const -{ +const shared_ptr + encoderFactory::getEncoderByName(const string& name) const { + const string lcName(utility::stringUtils::toLower(name)); for (std::vector >::const_iterator it = m_encoders.begin() ; - it != m_encoders.end() ; ++it) - { - if ((*it)->getName() == lcName) + it != m_encoders.end() ; ++it) { + + if ((*it)->getName() == lcName) { return (*it); + } } throw exceptions::no_encoder_available(name); } -size_t encoderFactory::getEncoderCount() const -{ - return (m_encoders.size()); +size_t encoderFactory::getEncoderCount() const { + + return m_encoders.size(); } -const shared_ptr encoderFactory::getEncoderAt(const size_t pos) const -{ - return (m_encoders[pos]); +const shared_ptr + encoderFactory::getEncoderAt(const size_t pos) const { + + return m_encoders[pos]; } -const std::vector > encoderFactory::getEncoderList() const -{ +const std::vector > + encoderFactory::getEncoderList() const { + std::vector > res; for (std::vector >::const_iterator it = m_encoders.begin() ; - it != m_encoders.end() ; ++it) - { + it != m_encoders.end() ; ++it) { + res.push_back(*it); } - return (res); + return res; } -void encoderFactory::setDefaultEncoder(const shared_ptr & enc) -{ +void encoderFactory::setDefaultEncoder(const shared_ptr & enc) { + m_defaultEncoder = enc; } -shared_ptr encoderFactory::getDefaultEncoder() const -{ +shared_ptr encoderFactory::getDefaultEncoder() const { + return m_defaultEncoder; } diff --git a/src/vmime/utility/encoder/encoderFactory.hpp b/src/vmime/utility/encoder/encoderFactory.hpp index 91121ad5..e475f8e8 100644 --- a/src/vmime/utility/encoder/encoderFactory.hpp +++ b/src/vmime/utility/encoder/encoderFactory.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,7 +36,6 @@ namespace encoder { /** A factory to create 'encoder' objects for the specified encoding. */ - class VMIME_EXPORT encoderFactory { private: @@ -49,8 +48,8 @@ public: static shared_ptr getInstance(); /** Information about a registered encoder. */ - class VMIME_EXPORT registeredEncoder : public object - { + class VMIME_EXPORT registeredEncoder : public object { + protected: virtual ~registeredEncoder() { } @@ -65,20 +64,20 @@ public: private: template - class registeredEncoderImpl : public registeredEncoder - { + class registeredEncoderImpl : public registeredEncoder { + public: registeredEncoderImpl(const string& name) : m_name(name) { } - shared_ptr create() const - { + shared_ptr create() const { + return vmime::make_shared (); } - const string& getName() const - { - return (m_name); + const string& getName() const { + + return m_name; } private: @@ -97,9 +96,11 @@ public: * @param name encoding name */ template - void registerName(const string& name) - { - m_encoders.push_back(vmime::make_shared >(utility::stringUtils::toLower(name))); + void registerName(const string& name) { + + m_encoders.push_back( + vmime::make_shared >(utility::stringUtils::toLower(name)) + ); } /** Create a new encoder instance from an encoding name. diff --git a/src/vmime/utility/encoder/noopEncoder.cpp b/src/vmime/utility/encoder/noopEncoder.cpp index 3d991b5d..30cc6c16 100644 --- a/src/vmime/utility/encoder/noopEncoder.cpp +++ b/src/vmime/utility/encoder/noopEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,14 +31,17 @@ namespace utility { namespace encoder { -noopEncoder::noopEncoder() -{ +noopEncoder::noopEncoder() { + } -size_t noopEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t noopEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // No encoding performed @@ -53,31 +56,35 @@ size_t noopEncoder::encode(utility::inputStream& in, } -size_t noopEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t noopEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // No decoding performed size_t res = 0; - if (progress) + if (progress) { res = utility::bufferedStreamCopy(in, out, 0, progress); - else + } else { res = utility::bufferedStreamCopy(in, out); + } return res; } -size_t noopEncoder::getEncodedSize(const size_t n) const -{ +size_t noopEncoder::getEncodedSize(const size_t n) const { + return n; } -size_t noopEncoder::getDecodedSize(const size_t n) const -{ +size_t noopEncoder::getDecodedSize(const size_t n) const { + return n; } diff --git a/src/vmime/utility/encoder/noopEncoder.hpp b/src/vmime/utility/encoder/noopEncoder.hpp index 6314812b..91944dee 100644 --- a/src/vmime/utility/encoder/noopEncoder.hpp +++ b/src/vmime/utility/encoder/noopEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Default, no-op encoder (simple copy, no encoding/decoding is performed). */ +class VMIME_EXPORT noopEncoder : public encoder { -class VMIME_EXPORT noopEncoder : public encoder -{ public: noopEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); size_t getEncodedSize(const size_t n) const; size_t getDecodedSize(const size_t n) const; diff --git a/src/vmime/utility/encoder/qpEncoder.cpp b/src/vmime/utility/encoder/qpEncoder.cpp index d4844ce7..4aeb6400 100644 --- a/src/vmime/utility/encoder/qpEncoder.cpp +++ b/src/vmime/utility/encoder/qpEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,13 +30,13 @@ namespace utility { namespace encoder { -qpEncoder::qpEncoder() -{ +qpEncoder::qpEncoder() { + } -const std::vector qpEncoder::getAvailableProperties() const -{ +const std::vector qpEncoder::getAvailableProperties() const { + std::vector list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); @@ -46,7 +46,7 @@ const std::vector qpEncoder::getAvailableProperties() const list.push_back("rfc2047"); // for header fields encoding (RFC #2047) - return (list); + return list; } @@ -69,8 +69,7 @@ const unsigned char qpEncoder::sm_hexDigits[] = "0123456789ABCDEF"; // This is a quick lookup table: // '1' means "encode", '0' means "no encoding" // -const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = -{ +const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = { /* 0 NUL */ 1, /* 1 SOH */ 1, /* 2 STX */ 1, /* 3 ETX */ 1, /* 4 EOT */ 1, /* 5 ENQ */ 1, /* 6 ACK */ 1, /* 7 BEL */ 1, /* 8 BS */ 1, /* 9 TAB */ 1, /* 10 LF */ 1, /* 11 VT */ 1, /* 12 FF */ 1, /* 13 CR */ 1, /* 14 SO */ 1, /* 15 SI */ 1, /* 16 DLE */ 1, /* 17 DC1 */ 1, @@ -97,8 +96,7 @@ const vmime_uint8 qpEncoder::sm_RFC2047EncodeTable[] = // Hex-decoding table -const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = -{ +const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -119,30 +117,30 @@ const vmime_uint8 qpEncoder::sm_hexDecodeTable[256] = // static -bool qpEncoder::RFC2047_isEncodingNeededForChar(const byte_t c) -{ - return (c >= 128 || sm_RFC2047EncodeTable[c] != 0); +bool qpEncoder::RFC2047_isEncodingNeededForChar(const byte_t c) { + + return c >= 128 || sm_RFC2047EncodeTable[c] != 0; } // static -int qpEncoder::RFC2047_getEncodedLength(const byte_t c) -{ - if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) - { - if (c == 32) // space - { +int qpEncoder::RFC2047_getEncodedLength(const byte_t c) { + + if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) { + + if (c == 32) { // space + // Encoded as "_" return 1; - } - else - { + + } else { + // Hex encoding return 3; } - } - else - { + + } else { + return 1; // no encoding } } @@ -162,9 +160,12 @@ int qpEncoder::RFC2047_getEncodedLength(const byte_t c) #endif // VMIME_BUILDING_DOC -size_t qpEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t qpEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const size_t propMaxLineLength = @@ -189,14 +190,15 @@ size_t qpEncoder::encode(utility::inputStream& in, size_t total = 0; size_t inTotal = 0; - if (progress) + if (progress) { progress->start(0); + } + + while (bufferPos < bufferLength || !in.eof()) { - while (bufferPos < bufferLength || !in.eof()) - { // Flush current output buffer - if (outBufferPos + 6 >= static_cast (sizeof(outBuffer))) - { + if (outBufferPos + 6 >= static_cast (sizeof(outBuffer))) { + QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; @@ -204,146 +206,146 @@ size_t qpEncoder::encode(utility::inputStream& in, } // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Get the next char and encode it const byte_t c = buffer[bufferPos++]; - if (rfc2047) - { - if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) - { - if (c == 32) // space - { + if (rfc2047) { + + if (c >= 128 || sm_RFC2047EncodeTable[c] != 0) { + + if (c == 32) { // space + // RFC-2047, Page 5, 4.2. The "Q" encoding: // << The 8-bit hexadecimal value 20 (e.g., ISO-8859-1 SPACE) may be // represented as "_" (underscore, ASCII 95.). >> outBuffer[outBufferPos++] = '_'; ++curCol; - } - else - { + + } else { + // Other characters: '=' + hexadecimal encoding QP_ENCODE_HEX(c); } - } - else - { + + } else { + // No encoding outBuffer[outBufferPos++] = c; ++curCol; } - } - else - { - switch (c) - { - case 46: // . - { - if (curCol == 0) - { - // If a '.' appears at the beginning of a line, we encode it to - // to avoid problems with SMTP servers... ("\r\n.\r\n" means the - // end of data transmission). - QP_ENCODE_HEX('.'); - continue; - } - outBuffer[outBufferPos++] = '.'; - ++curCol; - break; - } - case 32: // space - { - // Need to get more data? - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } + } else { - // Spaces cannot appear at the end of a line. So, encode the space. - if (bufferPos >= bufferLength || - (buffer[bufferPos] == '\r' || buffer[bufferPos] == '\n')) - { - QP_ENCODE_HEX(' '); - } - else - { - outBuffer[outBufferPos++] = ' '; + switch (c) { + + case 46: { // . + + if (curCol == 0) { + // If a '.' appears at the beginning of a line, we encode it to + // to avoid problems with SMTP servers... ("\r\n.\r\n" means the + // end of data transmission). + QP_ENCODE_HEX('.'); + continue; + } + + outBuffer[outBufferPos++] = '.'; ++curCol; + break; } + case 32: { // space - break; - } - case 9: // TAB - { - QP_ENCODE_HEX(c); - break; - } - case 13: // CR - case 10: // LF - { - // RFC-2045/6.7(4) + // Need to get more data? + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } - // Text data - if (text && !rfc2047) - { - outBuffer[outBufferPos++] = c; - ++curCol; + // Spaces cannot appear at the end of a line. So, encode the space. + if (bufferPos >= bufferLength || + (buffer[bufferPos] == '\r' || buffer[bufferPos] == '\n')) { - if (c == 10) - curCol = 0; // reset current line length + QP_ENCODE_HEX(' '); + + } else { + + outBuffer[outBufferPos++] = ' '; + ++curCol; + } + + break; } - // Binary data - else - { + case 9: { // TAB + QP_ENCODE_HEX(c); + break; } + case 13: // CR + case 10: { // LF - break; - } - case 61: // = - { - QP_ENCODE_HEX('='); - break; - } - /* - Rule #2: (Literal representation) Octets with decimal values of 33 - through 60 inclusive, and 62 through 126, inclusive, MAY be - represented as the ASCII characters which correspond to those - octets (EXCLAMATION POINT through LESS THAN, and GREATER THAN - through TILDE, respectively). - */ - default: + // RFC-2045/6.7(4) - //if ((c >= 33 && c <= 60) || (c >= 62 && c <= 126)) - if (c >= 33 && c <= 126 && c != 61 && c != 63) - { - outBuffer[outBufferPos++] = c; - ++curCol; - } - // Other characters: '=' + hexadecimal encoding - else - { - QP_ENCODE_HEX(c); + // Text data + if (text && !rfc2047) { + + outBuffer[outBufferPos++] = c; + ++curCol; + + if (c == 10) { + curCol = 0; // reset current line length + } + + // Binary data + } else { + + QP_ENCODE_HEX(c); + } + + break; } + case 61: { // = - break; + QP_ENCODE_HEX('='); + break; + } + /* + Rule #2: (Literal representation) Octets with decimal values of 33 + through 60 inclusive, and 62 through 126, inclusive, MAY be + represented as the ASCII characters which correspond to those + octets (EXCLAMATION POINT through LESS THAN, and GREATER THAN + through TILDE, respectively). + */ + default: + + //if ((c >= 33 && c <= 60) || (c >= 62 && c <= 126)) + if (c >= 33 && c <= 126 && c != 61 && c != 63) { + + outBuffer[outBufferPos++] = c; + ++curCol; + + // Other characters: '=' + hexadecimal encoding + } else { + + QP_ENCODE_HEX(c); + } + + break; } // switch (c) // Soft line break : "=\r\n" - if (cutLines && curCol >= maxLineLength - 1) - { + if (cutLines && curCol >= maxLineLength - 1) { + outBuffer[outBufferPos] = '='; outBuffer[outBufferPos + 1] = '\r'; outBuffer[outBufferPos + 2] = '\n'; @@ -356,27 +358,31 @@ size_t qpEncoder::encode(utility::inputStream& in, ++inTotal; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } // Flush remaining output buffer - if (outBufferPos != 0) - { + if (outBufferPos != 0) { QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t qpEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t qpEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -392,11 +398,11 @@ size_t qpEncoder::decode(utility::inputStream& in, size_t total = 0; size_t inTotal = 0; - while (bufferPos < bufferLength || !in.eof()) - { + while (bufferPos < bufferLength || !in.eof()) { + // Flush current output buffer - if (outBufferPos >= sizeof(outBuffer)) - { + if (outBufferPos >= sizeof(outBuffer)) { + QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; @@ -404,14 +410,15 @@ size_t qpEncoder::decode(utility::inputStream& in, } // Need to get more data? - if (bufferPos >= bufferLength) - { + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); bufferPos = 0; // No more data - if (bufferLength == 0) + if (bufferLength == 0) { break; + } } // Decode the next sequence (hex-encoded byte or printable character) @@ -419,125 +426,124 @@ size_t qpEncoder::decode(utility::inputStream& in, ++inTotal; - switch (c) - { - case '=': - { - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; + switch (c) { + + case '=': { + + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + if (bufferPos < bufferLength) { + + c = buffer[bufferPos++]; + + ++inTotal; + + switch (c) { + + // Ignore soft line break ("=\r\n" or "=\n") + case '\r': + + // Read one byte more + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + if (bufferPos < bufferLength) { + ++bufferPos; + ++inTotal; + } + + break; + + case '\n': + + break; + + // Hex-encoded char + default: + { + // We need another byte... + if (bufferPos >= bufferLength) { + bufferLength = in.read(buffer, sizeof(buffer)); + bufferPos = 0; + } + + if (bufferPos < bufferLength) { + + const byte_t next = buffer[bufferPos++]; + + ++inTotal; + + const byte_t value = static_cast ( + sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next] + ); + + outBuffer[outBufferPos++] = value; + + } else { + + // Premature end-of-data + } + + break; + } + + } + + } else { + + // Premature end-of-data + } + + break; } + case '_': { - if (bufferPos < bufferLength) - { - c = buffer[bufferPos++]; - - ++inTotal; - - switch (c) - { - // Ignore soft line break ("=\r\n" or "=\n") - case '\r': - - // Read one byte more - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } - - if (bufferPos < bufferLength) - { - ++bufferPos; - ++inTotal; - } - - break; - - case '\n': - - break; - - // Hex-encoded char - default: - { - // We need another byte... - if (bufferPos >= bufferLength) - { - bufferLength = in.read(buffer, sizeof(buffer)); - bufferPos = 0; - } - - if (bufferPos < bufferLength) - { - const byte_t next = buffer[bufferPos++]; - - ++inTotal; - - const byte_t value = static_cast - (sm_hexDecodeTable[c] * 16 + sm_hexDecodeTable[next]); - - outBuffer[outBufferPos++] = value; - } - else - { - // Premature end-of-data - } + if (rfc2047) { + // RFC-2047, Page 5, 4.2. The "Q" encoding: + // << Note that the "_" always represents hexadecimal 20, even if the SPACE + // character occupies a different code position in the character set in use. >> + outBuffer[outBufferPos++] = 0x20; break; } - } - } - else - { - // Premature end-of-data + outBuffer[outBufferPos++] = c; + break; } + default: { - break; - } - case '_': - { - if (rfc2047) - { - // RFC-2047, Page 5, 4.2. The "Q" encoding: - // << Note that the "_" always represents hexadecimal 20, even if the SPACE - // character occupies a different code position in the character set in use. >> - outBuffer[outBufferPos++] = 0x20; + outBuffer[outBufferPos++] = c; break; } - outBuffer[outBufferPos++] = c; - break; - } - default: - { - outBuffer[outBufferPos++] = c; } - } - - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } // Flush remaining output buffer - if (outBufferPos != 0) - { + if (outBufferPos != 0) { QP_WRITE(out, outBuffer, outBufferPos); total += outBufferPos; } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t qpEncoder::getEncodedSize(const size_t n) const -{ +size_t qpEncoder::getEncodedSize(const size_t n) const { + const size_t propMaxLineLength = getProperties().getProperty ("maxlinelength", static_cast (-1)); @@ -550,8 +556,8 @@ size_t qpEncoder::getEncodedSize(const size_t n) const } -size_t qpEncoder::getDecodedSize(const size_t n) const -{ +size_t qpEncoder::getDecodedSize(const size_t n) const { + // Worst case: 1 byte of input equals 1 byte of output return n; } diff --git a/src/vmime/utility/encoder/qpEncoder.hpp b/src/vmime/utility/encoder/qpEncoder.hpp index c666795b..21263a6b 100644 --- a/src/vmime/utility/encoder/qpEncoder.hpp +++ b/src/vmime/utility/encoder/qpEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** Quoted-printable encoder. */ +class VMIME_EXPORT qpEncoder : public encoder { -class VMIME_EXPORT qpEncoder : public encoder -{ public: qpEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector getAvailableProperties() const; diff --git a/src/vmime/utility/encoder/sevenBitEncoder.cpp b/src/vmime/utility/encoder/sevenBitEncoder.cpp index 7c76d73f..999b11e5 100644 --- a/src/vmime/utility/encoder/sevenBitEncoder.cpp +++ b/src/vmime/utility/encoder/sevenBitEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace utility { namespace encoder { -sevenBitEncoder::sevenBitEncoder() -{ +sevenBitEncoder::sevenBitEncoder() { + } diff --git a/src/vmime/utility/encoder/sevenBitEncoder.hpp b/src/vmime/utility/encoder/sevenBitEncoder.hpp index d260cc7b..37f84a61 100644 --- a/src/vmime/utility/encoder/sevenBitEncoder.hpp +++ b/src/vmime/utility/encoder/sevenBitEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,7 +35,6 @@ namespace encoder { /** 7-bit encoder. */ - class VMIME_EXPORT sevenBitEncoder : public noopEncoder { public: diff --git a/src/vmime/utility/encoder/uuEncoder.cpp b/src/vmime/utility/encoder/uuEncoder.cpp index 5ee2c2b1..24dcdc8b 100644 --- a/src/vmime/utility/encoder/uuEncoder.cpp +++ b/src/vmime/utility/encoder/uuEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,16 +30,16 @@ namespace utility { namespace encoder { -uuEncoder::uuEncoder() -{ +uuEncoder::uuEncoder() { + getProperties()["mode"] = 644; getProperties()["filename"] = "no_name"; getProperties()["maxlinelength"] = 46; } -const std::vector uuEncoder::getAvailableProperties() const -{ +const std::vector uuEncoder::getAvailableProperties() const { + std::vector list(encoder::getAvailableProperties()); list.push_back("maxlinelength"); @@ -47,26 +47,29 @@ const std::vector uuEncoder::getAvailableProperties() const list.push_back("mode"); list.push_back("filename"); - return (list); + return list; } // This is the character encoding function to make a character printable -static inline byte_t UUENCODE(const unsigned int c) -{ +static inline byte_t UUENCODE(const unsigned int c) { + return static_cast ((c & 077) + ' '); } // Single character decoding -static inline unsigned int UUDECODE(const unsigned int c) -{ +static inline unsigned int UUDECODE(const unsigned int c) { + return (c - ' ') & 077; } -size_t uuEncoder::encode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t uuEncoder::encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... const string propFilename = getProperties().getProperty ("filename", ""); @@ -81,8 +84,7 @@ size_t uuEncoder::encode(utility::inputStream& in, // Output the prelude text ("begin [mode] [filename]") out << "begin"; - if (!propFilename.empty()) - { + if (!propFilename.empty()) { out << " " << propMode << " " << propFilename; total += 2 + propMode.length() + propFilename.length(); } @@ -94,11 +96,12 @@ size_t uuEncoder::encode(utility::inputStream& in, byte_t inBuffer[64]; byte_t outBuffer[64]; - if (progress) + if (progress) { progress->start(0); + } + + while (!in.eof()) { - while (!in.eof()) - { // Process up to 45 characters per line std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); @@ -108,8 +111,8 @@ size_t uuEncoder::encode(utility::inputStream& in, size_t j = 1; - for (size_t i = 0 ; i < inLength ; i += 3, j += 4) - { + for (size_t i = 0 ; i < inLength ; i += 3, j += 4) { + const byte_t c1 = inBuffer[i]; const byte_t c2 = inBuffer[i + 1]; const byte_t c3 = inBuffer[i + 2]; @@ -128,23 +131,28 @@ size_t uuEncoder::encode(utility::inputStream& in, total += j + 2; inTotal += inLength; - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } out << "end\r\n"; total += 5; - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t uuEncoder::decode(utility::inputStream& in, - utility::outputStream& out, utility::progressListener* progress) -{ +size_t uuEncoder::decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress +) { + in.reset(); // may not work... // Process the data @@ -158,128 +166,131 @@ size_t uuEncoder::decode(utility::inputStream& in, std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); - if (progress) + if (progress) { progress->start(0); + } + + while (!stop && !in.eof()) { - while (!stop && !in.eof()) - { // Get the line length byte_t lengthChar; - if (in.read(&lengthChar, 1) == 0) + if (in.read(&lengthChar, 1) == 0) { break; + } const size_t outLength = UUDECODE(lengthChar); const size_t inLength = std::min((outLength * 4) / 3, static_cast (64)); size_t inPos = 0; - switch (lengthChar) - { - case ' ': - case '\t': - case '\r': - case '\n': - { - // Ignore - continue; - } - case 'b': - { - // Read 5 characters more to check for begin ("begin ...\r\n" or "begin ...\n") - inPos = in.read(inBuffer, 5); + switch (lengthChar) { - if (inPos == 5 && - inBuffer[0] == 'e' && - inBuffer[1] == 'g' && - inBuffer[2] == 'i' && - inBuffer[3] == 'n' && - parserHelpers::isSpace(inBuffer[4])) - { - inTotal += 5; - - byte_t c = 0; - - size_t count = 0; - byte_t buffer[512]; - - while (count < sizeof(buffer) - 1 && in.read(&c, 1) == 1) - { - if (c == '\n') - break; - - buffer[count++] = c; - } - - inTotal += count; - - if (c != '\n') - { - // OOPS! Weird line. Don't try to decode more... - - if (progress) - progress->stop(inTotal); - - return (total); - } - - // Parse filename and mode - if (count > 0) - { - buffer[count] = '\0'; - - byte_t* p = buffer; - - while (*p && parserHelpers::isSpace(*p)) ++p; - - byte_t* modeStart = buffer; - - while (*p && !parserHelpers::isSpace(*p)) ++p; - - getResults()["mode"] = string(modeStart, p); - - while (*p && parserHelpers::isSpace(*p)) ++p; - - byte_t* filenameStart = buffer; - - while (*p && !(*p == '\r' || *p == '\n')) ++p; - - getResults()["filename"] = string(filenameStart, p); - } - // No filename or mode specified - else - { - getResults()["filename"] = "untitled"; - getResults()["mode"] = 644; - } + case ' ': + case '\t': + case '\r': + case '\n': { + // Ignore continue; } + case 'b': { - break; - } - case 'e': - { - // Read 3 characters more to check for end ("end\r\n" or "end\n") - inPos = in.read(inBuffer, 3); + // Read 5 characters more to check for begin ("begin ...\r\n" or "begin ...\n") + inPos = in.read(inBuffer, 5); - if (inPos == 3 && - inBuffer[0] == 'n' && - inBuffer[1] == 'd' && - (inBuffer[2] == '\r' || inBuffer[2] == '\n')) - { - stop = true; - inTotal += 3; - continue; + if (inPos == 5 && + inBuffer[0] == 'e' && + inBuffer[1] == 'g' && + inBuffer[2] == 'i' && + inBuffer[3] == 'n' && + parserHelpers::isSpace(inBuffer[4])) { + + inTotal += 5; + + byte_t c = 0; + + size_t count = 0; + byte_t buffer[512]; + + while (count < sizeof(buffer) - 1 && in.read(&c, 1) == 1) { + + if (c == '\n') { + break; + } + + buffer[count++] = c; + } + + inTotal += count; + + if (c != '\n') { + + // OOPS! Weird line. Don't try to decode more... + + if (progress) { + progress->stop(inTotal); + } + + return total; + } + + // Parse filename and mode + if (count > 0) { + + buffer[count] = '\0'; + + byte_t* p = buffer; + + while (*p && parserHelpers::isSpace(*p)) ++p; + + byte_t* modeStart = buffer; + + while (*p && !parserHelpers::isSpace(*p)) ++p; + + getResults()["mode"] = string(modeStart, p); + + while (*p && parserHelpers::isSpace(*p)) ++p; + + byte_t* filenameStart = buffer; + + while (*p && !(*p == '\r' || *p == '\n')) ++p; + + getResults()["filename"] = string(filenameStart, p); + + // No filename or mode specified + } else { + + getResults()["filename"] = "untitled"; + getResults()["mode"] = 644; + } + + continue; + } + + break; } + case 'e': { - break; - } + // Read 3 characters more to check for end ("end\r\n" or "end\n") + inPos = in.read(inBuffer, 3); + + if (inPos == 3 && + inBuffer[0] == 'n' && + inBuffer[1] == 'd' && + (inBuffer[2] == '\r' || inBuffer[2] == '\n')) { + + stop = true; + inTotal += 3; + continue; + } + + break; + } } // Read encoded data - if (in.read(inBuffer + inPos, inLength - inPos) != inLength - inPos) - { + if (in.read(inBuffer + inPos, inLength - inPos) != inLength - inPos) { // Premature end of data break; } @@ -287,8 +298,8 @@ size_t uuEncoder::decode(utility::inputStream& in, inTotal += (inLength - inPos); // Decode data - for (size_t i = 0, j = 0 ; i < inLength ; i += 4, j += 3) - { + for (size_t i = 0, j = 0 ; i < inLength ; i += 4, j += 3) { + const byte_t c1 = inBuffer[i]; const byte_t c2 = inBuffer[i + 1]; const byte_t c3 = inBuffer[i + 2]; @@ -296,12 +307,15 @@ size_t uuEncoder::decode(utility::inputStream& in, const size_t n = std::min(inLength - i, static_cast (3)); - if (n >= 3) + if (n >= 3) { outBuffer[j + 2] = static_cast (UUDECODE(c3) << 6 | UUDECODE(c4)); - if (n >= 2) + } + if (n >= 2) { outBuffer[j + 1] = static_cast (UUDECODE(c2) << 4 | UUDECODE(c3) >> 2); - if (n >= 1) + } + if (n >= 1) { outBuffer[j] = static_cast (UUDECODE(c1) << 2 | UUDECODE(c2) >> 4); + } total += n; } @@ -310,19 +324,21 @@ size_t uuEncoder::decode(utility::inputStream& in, std::fill(inBuffer, inBuffer + sizeof(inBuffer), 0); - if (progress) + if (progress) { progress->progress(inTotal, inTotal); + } } - if (progress) + if (progress) { progress->stop(inTotal); + } - return (total); + return total; } -size_t uuEncoder::getEncodedSize(const size_t n) const -{ +size_t uuEncoder::getEncodedSize(const size_t n) const { + // 3 bytes of input provide 4 bytes of output. // Count CRLF (2 bytes) for each line of 45 characters. // Also reserve some space for header and footer. @@ -330,8 +346,8 @@ size_t uuEncoder::getEncodedSize(const size_t n) const } -size_t uuEncoder::getDecodedSize(const size_t n) const -{ +size_t uuEncoder::getDecodedSize(const size_t n) const { + // 4 bytes of input provide 3 bytes of output return (n * 3) / 4; } diff --git a/src/vmime/utility/encoder/uuEncoder.hpp b/src/vmime/utility/encoder/uuEncoder.hpp index 7365263c..841cf660 100644 --- a/src/vmime/utility/encoder/uuEncoder.hpp +++ b/src/vmime/utility/encoder/uuEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,15 +35,23 @@ namespace encoder { /** UUEncode encoder. */ +class VMIME_EXPORT uuEncoder : public encoder { -class VMIME_EXPORT uuEncoder : public encoder -{ public: uuEncoder(); - size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); - size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t encode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); + + size_t decode( + utility::inputStream& in, + utility::outputStream& out, + utility::progressListener* progress = NULL + ); const std::vector getAvailableProperties() const; diff --git a/src/vmime/utility/file.hpp b/src/vmime/utility/file.hpp index c0ba2c5b..6e0605e1 100644 --- a/src/vmime/utility/file.hpp +++ b/src/vmime/utility/file.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,9 +43,8 @@ class file; /** File list iterator (see file::getFiles). */ +class VMIME_EXPORT fileIterator : public object { -class VMIME_EXPORT fileIterator : public object -{ public: virtual ~fileIterator() { } @@ -67,9 +66,8 @@ public: /** Write to a file. */ +class VMIME_EXPORT fileWriter : public object { -class VMIME_EXPORT fileWriter : public object -{ public: virtual ~fileWriter() { } @@ -80,9 +78,8 @@ public: /** Read from a file. */ +class VMIME_EXPORT fileReader : public object { -class VMIME_EXPORT fileReader : public object -{ public: virtual ~fileReader() { } @@ -93,9 +90,8 @@ public: /** Abstract representation of a file or directory. */ +class VMIME_EXPORT file : public object { -class VMIME_EXPORT file : public object -{ public: typedef utility::path path; @@ -213,9 +209,8 @@ private: /** Constructs 'file' objects. */ +class VMIME_EXPORT fileSystemFactory : public object { -class VMIME_EXPORT fileSystemFactory : public object -{ public: virtual ~fileSystemFactory() { } diff --git a/src/vmime/utility/filteredStream.cpp b/src/vmime/utility/filteredStream.cpp index 99ba13fd..d5ec17b7 100644 --- a/src/vmime/utility/filteredStream.cpp +++ b/src/vmime/utility/filteredStream.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,16 +32,16 @@ namespace utility { // filteredInputStream -size_t filteredInputStream::getBlockSize() -{ +size_t filteredInputStream::getBlockSize() { + return std::min(inputStream::getBlockSize(), getPreviousInputStream().getBlockSize()); } // filteredOutputStream -size_t filteredOutputStream::getBlockSize() -{ +size_t filteredOutputStream::getBlockSize() { + return std::min(outputStream::getBlockSize(), getNextOutputStream().getBlockSize()); } @@ -49,25 +49,27 @@ size_t filteredOutputStream::getBlockSize() // dotFilteredInputStream dotFilteredInputStream::dotFilteredInputStream(inputStream& is) - : m_stream(is), m_previousChar2('\0'), m_previousChar1('\0') -{ + : m_stream(is), + m_previousChar2('\0'), + m_previousChar1('\0') { + } -inputStream& dotFilteredInputStream::getPreviousInputStream() -{ - return (m_stream); +inputStream& dotFilteredInputStream::getPreviousInputStream() { + + return m_stream; } -bool dotFilteredInputStream::eof() const -{ - return (m_stream.eof()); +bool dotFilteredInputStream::eof() const { + + return m_stream.eof(); } -void dotFilteredInputStream::reset() -{ +void dotFilteredInputStream::reset() { + m_previousChar2 = '\0'; m_previousChar1 = '\0'; @@ -75,8 +77,8 @@ void dotFilteredInputStream::reset() } -size_t dotFilteredInputStream::read(byte_t* const data, const size_t count) -{ +size_t dotFilteredInputStream::read(byte_t* const data, const size_t count) { + const size_t read = m_stream.read(data, count); const byte_t* readPtr = data; @@ -90,16 +92,16 @@ size_t dotFilteredInputStream::read(byte_t* const data, const size_t count) byte_t prevChar1 = m_previousChar1; // Replace "\n.." with "\n." - while (readPtr < end) - { - if (*readPtr == '.' && prevChar2 == '\n' && prevChar1 == '.') - { + while (readPtr < end) { + + if (*readPtr == '.' && prevChar2 == '\n' && prevChar1 == '.') { + // Ignore last dot prevChar2 = '\0'; prevChar1 = '.'; - } - else - { + + } else { + *writePtr = *readPtr; ++writePtr; @@ -115,12 +117,12 @@ size_t dotFilteredInputStream::read(byte_t* const data, const size_t count) m_previousChar2 = prevChar2; m_previousChar1 = prevChar1; - return (written); + return written; } -size_t dotFilteredInputStream::skip(const size_t /* count */) -{ +size_t dotFilteredInputStream::skip(const size_t /* count */) { + // Skipping bytes is not supported return 0; } @@ -129,31 +131,33 @@ size_t dotFilteredInputStream::skip(const size_t /* count */) // dotFilteredOutputStream dotFilteredOutputStream::dotFilteredOutputStream(outputStream& os) - : m_stream(os), m_previousChar('\0'), m_start(true) -{ + : m_stream(os), + m_previousChar('\0'), + m_start(true) { + } -outputStream& dotFilteredOutputStream::getNextOutputStream() -{ - return (m_stream); +outputStream& dotFilteredOutputStream::getNextOutputStream() { + + return m_stream; } -void dotFilteredOutputStream::writeImpl - (const byte_t* const data, const size_t count) -{ - if (count == 0) +void dotFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) { + + if (count == 0) { return; + } const byte_t* pos = data; const byte_t* end = data + count; const byte_t* start = data; - if (m_previousChar == '.') - { - if (data[0] == '\n' || data[0] == '\r') - { + if (m_previousChar == '.') { + + if (data[0] == '\n' || data[0] == '\r') { + m_stream.write(".", 1); // extra m_stream.write(data, 1); @@ -162,26 +166,26 @@ void dotFilteredOutputStream::writeImpl } // Replace "\n." with "\n.." - while ((pos = std::find(pos, end, '.')) != end) - { - const byte_t previousChar = - (pos == data ? m_previousChar : *(pos - 1)); + while ((pos = std::find(pos, end, '.')) != end) { + + const byte_t previousChar = (pos == data ? m_previousChar : *(pos - 1)); + + if (previousChar == '\n') { - if (previousChar == '\n') - { m_stream.write(start, pos - start); m_stream.write("..", 2); start = pos + 1; - } - else if (pos == data && m_start) // at the beginning of content - { + + } else if (pos == data && m_start) { // at the beginning of content + m_stream.write(start, pos - start); - if (pos + 1 < end && (*(pos + 1) == '\n' || *(pos + 1) == '\r')) + if (pos + 1 < end && (*(pos + 1) == '\n' || *(pos + 1) == '\r')) { m_stream.write("..", 2); - else + } else { m_stream.write(".", 1); + } start = pos + 1; } @@ -195,15 +199,15 @@ void dotFilteredOutputStream::writeImpl } -void dotFilteredOutputStream::flush() -{ +void dotFilteredOutputStream::flush() { + // Do nothing m_stream.flush(); } -size_t dotFilteredOutputStream::getBlockSize() -{ +size_t dotFilteredOutputStream::getBlockSize() { + return m_stream.getBlockSize(); } @@ -211,22 +215,23 @@ size_t dotFilteredOutputStream::getBlockSize() // CRLFToLFFilteredOutputStream CRLFToLFFilteredOutputStream::CRLFToLFFilteredOutputStream(outputStream& os) - : m_stream(os), m_previousChar('\0') -{ + : m_stream(os), + m_previousChar('\0') { + } -outputStream& CRLFToLFFilteredOutputStream::getNextOutputStream() -{ - return (m_stream); +outputStream& CRLFToLFFilteredOutputStream::getNextOutputStream() { + + return m_stream; } -void CRLFToLFFilteredOutputStream::writeImpl - (const byte_t* const data, const size_t count) -{ - if (count == 0) +void CRLFToLFFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) { + + if (count == 0) { return; + } const byte_t* pos = data; const byte_t* end = data + count; @@ -235,25 +240,24 @@ void CRLFToLFFilteredOutputStream::writeImpl // Warning: if the whole buffer finishes with '\r', this // last character will not be written back if flush() is // not called - if (m_previousChar == '\r') - { - if (*pos != '\n') - { + if (m_previousChar == '\r') { + + if (*pos != '\n') { m_stream.write("\r", 1); // write back \r m_previousChar = *pos; } } // Replace "\r\n" (CRLF) with "\n" (LF) - while ((pos = std::find(pos, end, '\n')) != end) - { - const byte_t previousChar = - (pos == data ? m_previousChar : *(pos - 1)); + while ((pos = std::find(pos, end, '\n')) != end) { - if (previousChar == '\r') - { - if (pos != start) + const byte_t previousChar = (pos == data ? m_previousChar : *(pos - 1)); + + if (previousChar == '\r') { + + if (pos != start) { m_stream.write(start, pos - 1 - start); // do not write \r + } m_stream.write("\n", 1); @@ -263,29 +267,29 @@ void CRLFToLFFilteredOutputStream::writeImpl ++pos; } - if (data[count - 1] == '\r') - { + if (data[count - 1] == '\r') { + m_stream.write(start, end - start - 1); m_previousChar = '\r'; - } - else - { + + } else { + m_stream.write(start, end - start); m_previousChar = data[count - 1]; } } -void CRLFToLFFilteredOutputStream::flush() -{ +void CRLFToLFFilteredOutputStream::flush() { + m_stream.flush(); // TODO } -size_t CRLFToLFFilteredOutputStream::getBlockSize() -{ +size_t CRLFToLFFilteredOutputStream::getBlockSize() { + return m_stream.getBlockSize(); } @@ -293,22 +297,23 @@ size_t CRLFToLFFilteredOutputStream::getBlockSize() // LFToCRLFFilteredOutputStream LFToCRLFFilteredOutputStream::LFToCRLFFilteredOutputStream(outputStream& os) - : m_stream(os), m_previousChar('\0') -{ + : m_stream(os), + m_previousChar('\0') { + } -outputStream& LFToCRLFFilteredOutputStream::getNextOutputStream() -{ - return (m_stream); +outputStream& LFToCRLFFilteredOutputStream::getNextOutputStream() { + + return m_stream; } -void LFToCRLFFilteredOutputStream::writeImpl - (const byte_t* const data, const size_t count) +void LFToCRLFFilteredOutputStream::writeImpl(const byte_t* const data, const size_t count) { - if (count == 0) + if (count == 0) { return; + } string buffer; buffer.reserve(count); @@ -318,31 +323,30 @@ void LFToCRLFFilteredOutputStream::writeImpl byte_t previousChar = m_previousChar; - while (pos < end) - { - switch (*pos) - { - case '\r': + while (pos < end) { - buffer.append(1, '\r'); - buffer.append(1, '\n'); + switch (*pos) { - break; + case '\r': - case '\n': - - if (previousChar != '\r') - { buffer.append(1, '\r'); buffer.append(1, '\n'); - } - break; + break; - default: + case '\n': - buffer.append(1, *pos); - break; + if (previousChar != '\r') { + buffer.append(1, '\r'); + buffer.append(1, '\n'); + } + + break; + + default: + + buffer.append(1, *pos); + break; } previousChar = *pos; @@ -355,14 +359,14 @@ void LFToCRLFFilteredOutputStream::writeImpl } -void LFToCRLFFilteredOutputStream::flush() -{ +void LFToCRLFFilteredOutputStream::flush() { + m_stream.flush(); } -size_t LFToCRLFFilteredOutputStream::getBlockSize() -{ +size_t LFToCRLFFilteredOutputStream::getBlockSize() { + return m_stream.getBlockSize(); } @@ -370,11 +374,9 @@ size_t LFToCRLFFilteredOutputStream::getBlockSize() // stopSequenceFilteredInputStream <1> template <> -size_t stopSequenceFilteredInputStream <1>::read - (byte_t* const data, const size_t count) -{ - if (eof() || m_stream.eof()) - { +size_t stopSequenceFilteredInputStream <1>::read(byte_t* const data, const size_t count) { + + if (eof() || m_stream.eof()) { m_eof = true; return 0; } @@ -384,18 +386,17 @@ size_t stopSequenceFilteredInputStream <1>::read byte_t* pos = std::find(data, end, m_sequence[0]); - if (pos == end) - { - return (read); - } - else - { + if (pos == end) { + + return read; + + } else { + m_found = 1; - return (pos - data); + return pos - data; } } } // utility } // vmime - diff --git a/src/vmime/utility/filteredStream.hpp b/src/vmime/utility/filteredStream.hpp index e01e5e9d..2414c54d 100644 --- a/src/vmime/utility/filteredStream.hpp +++ b/src/vmime/utility/filteredStream.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,7 @@ namespace utility { /** A stream whose input is filtered. */ - -class VMIME_EXPORT filteredInputStream : public inputStream -{ +class VMIME_EXPORT filteredInputStream : public inputStream { public: virtual size_t getBlockSize(); @@ -54,9 +52,8 @@ public: /** A stream whose output is filtered. */ +class VMIME_EXPORT filteredOutputStream : public outputStream { -class VMIME_EXPORT filteredOutputStream : public outputStream -{ public: virtual size_t getBlockSize(); @@ -72,9 +69,8 @@ public: /** A filtered input stream which replaces "\n.." * sequences with "\n." sequences. */ +class VMIME_EXPORT dotFilteredInputStream : public filteredInputStream { -class VMIME_EXPORT dotFilteredInputStream : public filteredInputStream -{ public: /** Construct a new filter for the specified input stream. @@ -105,9 +101,8 @@ private: /** A filtered output stream which replaces "\n." * sequences with "\n.." sequences. */ +class VMIME_EXPORT dotFilteredOutputStream : public filteredOutputStream { -class VMIME_EXPORT dotFilteredOutputStream : public filteredOutputStream -{ public: /** Construct a new filter for the specified output stream. @@ -137,9 +132,8 @@ private: /** A filtered output stream which replaces CRLF sequences * with single LF characters. */ +class VMIME_EXPORT CRLFToLFFilteredOutputStream : public filteredOutputStream { -class VMIME_EXPORT CRLFToLFFilteredOutputStream : public filteredOutputStream -{ public: /** Construct a new filter for the specified output stream. @@ -160,7 +154,7 @@ protected: private: - outputStream& m_stream; + outputStream& m_stream; byte_t m_previousChar; }; @@ -168,9 +162,8 @@ private: /** A filtered output stream which replaces CR or LF characters * with CRLF sequences. */ +class VMIME_EXPORT LFToCRLFFilteredOutputStream : public filteredOutputStream { -class VMIME_EXPORT LFToCRLFFilteredOutputStream : public filteredOutputStream -{ public: /** Construct a new filter for the specified output stream. @@ -199,10 +192,9 @@ private: /** A filtered input stream which stops when a specified sequence * is found (eof() method will return 'true'). */ - template -class VMIME_EXPORT stopSequenceFilteredInputStream : public filteredInputStream -{ +class VMIME_EXPORT stopSequenceFilteredInputStream : public filteredInputStream { + public: /** Construct a new filter for the specified input stream. @@ -211,8 +203,11 @@ public: * @param sequence sequence on which to stop */ stopSequenceFilteredInputStream(inputStream& is, const byte_t* sequence) - : m_stream(is), m_sequence(sequence), m_found(0), m_eof(false) - { + : m_stream(is), + m_sequence(sequence), + m_found(0), + m_eof(false) { + } /** Construct a new filter for the specified input stream. @@ -221,49 +216,53 @@ public: * @param sequence sequence on which to stop */ stopSequenceFilteredInputStream(inputStream& is, const char* sequence) - : m_stream(is), m_sequence(reinterpret_cast (sequence)), - m_found(0), m_eof(false) - { + : m_stream(is), + m_sequence(reinterpret_cast (sequence)), + m_found(0), + m_eof(false) { + } - inputStream& getPreviousInputStream() - { - return (m_stream); + inputStream& getPreviousInputStream() { + + return m_stream; } - bool eof() const - { - return (m_found == COUNT || m_eof); + bool eof() const { + + return m_found == COUNT || m_eof; } - void reset() - { + void reset() { + m_found = 0; m_stream.reset(); } - size_t read(byte_t* const data, const size_t count) - { - // Read buffer must be at least 'COUNT' size + 1 byte - if (eof() || count <= COUNT) - return 0; + size_t read(byte_t* const data, const size_t count) { + + // Read buffer must be at least 'COUNT' size + 1 byte + if (eof() || count <= COUNT) { + return 0; + } + + if (m_stream.eof()) { + + if (m_found != 0) { - if (m_stream.eof()) - { - if (m_found != 0) - { const size_t found = m_found; - for (size_t f = 0 ; f < found ; ++f) + for (size_t f = 0 ; f < found ; ++f) { data[f] = m_sequence[f]; + } m_found = 0; m_eof = true; - return (found); - } - else - { + return found; + + } else { + m_eof = true; return 0; } @@ -274,72 +273,71 @@ public: byte_t* end = data + read; byte_t* pos = data; - while (pos < end) - { + while (pos < end) { + // Very simple case, search for the whole sequence - if (m_found == 0) - { - while (pos < end) - { + if (m_found == 0) { + + while (pos < end) { + pos = std::find(pos, end, m_sequence[0]); - if (pos == end) - return (read); + if (pos == end) { + return read; + } m_found = 1; ++pos; - while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) - { + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) { ++m_found; ++pos; } // Didn't found whole sequence - if (m_found != COUNT) - { + if (m_found != COUNT) { + // We reached the end of the buffer - if (pos == end) - { - return (read - m_found); - } + if (pos == end) { + + return read - m_found; + // Common prefix but not whole sequence - else - { + } else { + m_found = 0; } - } + // Whole sequence found - else - { + } else { + // End of stream - return (pos - data - m_found); + return pos - data - m_found; } } - } + // More complex case: search for a sequence which has begun // in a previous buffer - else - { + } else { + // Search for the end of the previously started sequence - while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) - { + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) { ++m_found; ++pos; } - if (m_found != COUNT) - { + if (m_found != COUNT) { + // End of buffer - if (pos == end) - { + if (pos == end) { + // No data: this buffer is a sub-sequence of the // searched sequence return 0; - } + // Common prefix - else - { + } else { + // We have to reinject the incomplete sequence into // the stream data @@ -349,8 +347,8 @@ public: byte_t* newEnd = data + read + m_found - n; byte_t* oldEnd = data + read; - for (size_t i = 0 ; i < read - n ; ++i) - { + for (size_t i = 0 ; i < read - n ; ++i) { + --newEnd; --oldEnd; @@ -358,17 +356,18 @@ public: } // -- copy the prefix just before data - for (size_t f = 0 ; f < m_found ; ++f) + for (size_t f = 0 ; f < m_found ; ++f) { data[f] = m_sequence[f]; + } read += m_found - n; end += m_found - n; m_found = 0; } - } - else - { + + } else { + return 0; // no more data } } @@ -377,8 +376,8 @@ public: return read; } - size_t skip(const size_t /* count */) - { + size_t skip(const size_t /* count */) { + // Not supported return 0; } @@ -395,8 +394,7 @@ private: template <> -size_t stopSequenceFilteredInputStream <1>::read - (byte_t* const data, const size_t count); +size_t stopSequenceFilteredInputStream <1>::read(byte_t* const data, const size_t count); } // utility diff --git a/src/vmime/utility/inputStream.cpp b/src/vmime/utility/inputStream.cpp index a7d6bc0f..916d8baa 100644 --- a/src/vmime/utility/inputStream.cpp +++ b/src/vmime/utility/inputStream.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/utility/inputStream.hpp b/src/vmime/utility/inputStream.hpp index 809996ce..0e1c2df8 100644 --- a/src/vmime/utility/inputStream.hpp +++ b/src/vmime/utility/inputStream.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** Simple input stream. */ +class VMIME_EXPORT inputStream : public stream { -class VMIME_EXPORT inputStream : public stream -{ public: /** Test for end of stream (no more data to read). diff --git a/src/vmime/utility/inputStreamAdapter.cpp b/src/vmime/utility/inputStreamAdapter.cpp index c0b06be4..28be1038 100644 --- a/src/vmime/utility/inputStreamAdapter.cpp +++ b/src/vmime/utility/inputStreamAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,50 +29,51 @@ namespace utility { inputStreamAdapter::inputStreamAdapter(std::istream& is) - : m_stream(is) -{ + : m_stream(is) { + } -bool inputStreamAdapter::eof() const -{ - return (m_stream.eof()); +bool inputStreamAdapter::eof() const { + + return m_stream.eof(); } -void inputStreamAdapter::reset() -{ +void inputStreamAdapter::reset() { + m_stream.exceptions(std::ios_base::badbit); m_stream.seekg(0, std::ios::beg); m_stream.clear(); } -size_t inputStreamAdapter::read - (byte_t* const data, const size_t count) -{ +size_t inputStreamAdapter::read(byte_t* const data, const size_t count) { + m_stream.exceptions(std::ios_base::badbit); m_stream.read(reinterpret_cast (data), count); - return (m_stream.gcount()); + + return m_stream.gcount(); } -size_t inputStreamAdapter::skip(const size_t count) -{ +size_t inputStreamAdapter::skip(const size_t count) { + m_stream.exceptions(std::ios_base::badbit); m_stream.ignore(count); - return (m_stream.gcount()); + + return m_stream.gcount(); } -size_t inputStreamAdapter::getPosition() const -{ +size_t inputStreamAdapter::getPosition() const { + return m_stream.tellg(); } -void inputStreamAdapter::seek(const size_t pos) -{ +void inputStreamAdapter::seek(const size_t pos) { + m_stream.clear(); m_stream.seekg(pos, std::ios_base::beg); } diff --git a/src/vmime/utility/inputStreamAdapter.hpp b/src/vmime/utility/inputStreamAdapter.hpp index dd761736..340765c3 100644 --- a/src/vmime/utility/inputStreamAdapter.hpp +++ b/src/vmime/utility/inputStreamAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,8 @@ namespace utility { /** An adapter class for C++ standard input streams. */ +class VMIME_EXPORT inputStreamAdapter : public seekableInputStream { -class VMIME_EXPORT inputStreamAdapter : public seekableInputStream -{ public: /** @param is input stream to wrap diff --git a/src/vmime/utility/inputStreamByteBufferAdapter.cpp b/src/vmime/utility/inputStreamByteBufferAdapter.cpp index c270ea56..927215c3 100644 --- a/src/vmime/utility/inputStreamByteBufferAdapter.cpp +++ b/src/vmime/utility/inputStreamByteBufferAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,37 +29,38 @@ namespace utility { inputStreamByteBufferAdapter::inputStreamByteBufferAdapter(const byte_t* buffer, const size_t length) - : m_buffer(buffer), m_length(length), m_pos(0) -{ + : m_buffer(buffer), + m_length(length), + m_pos(0) { + } -bool inputStreamByteBufferAdapter::eof() const -{ +bool inputStreamByteBufferAdapter::eof() const { + return m_pos >= m_length; } -void inputStreamByteBufferAdapter::reset() -{ +void inputStreamByteBufferAdapter::reset() { + m_pos = 0; } -size_t inputStreamByteBufferAdapter::read - (byte_t* const data, const size_t count) -{ +size_t inputStreamByteBufferAdapter::read(byte_t* const data, const size_t count) { + const size_t remaining = m_length - m_pos; - if (remaining < count) - { + if (remaining < count) { + std::copy(m_buffer + m_pos, m_buffer + m_pos + remaining, data); m_pos += remaining; return remaining; - } - else - { + + } else { + std::copy(m_buffer + m_pos, m_buffer + m_pos + count, data); m_pos += count; @@ -68,36 +69,36 @@ size_t inputStreamByteBufferAdapter::read } -size_t inputStreamByteBufferAdapter::skip(const size_t count) -{ +size_t inputStreamByteBufferAdapter::skip(const size_t count) { + const size_t remaining = m_length - m_pos; - if (remaining < count) - { + if (remaining < count) { + m_pos += remaining; return remaining; - } - else - { + + } else { + m_pos += count; return count; } } -size_t inputStreamByteBufferAdapter::getPosition() const -{ +size_t inputStreamByteBufferAdapter::getPosition() const { + return m_pos; } -void inputStreamByteBufferAdapter::seek(const size_t pos) -{ - if (pos <= m_length) +void inputStreamByteBufferAdapter::seek(const size_t pos) { + + if (pos <= m_length) { m_pos = pos; + } } } // utility } // vmime - diff --git a/src/vmime/utility/inputStreamByteBufferAdapter.hpp b/src/vmime/utility/inputStreamByteBufferAdapter.hpp index f201f433..c9094c79 100644 --- a/src/vmime/utility/inputStreamByteBufferAdapter.hpp +++ b/src/vmime/utility/inputStreamByteBufferAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An adapter class for reading from an array of bytes. */ +class VMIME_EXPORT inputStreamByteBufferAdapter : public seekableInputStream { -class VMIME_EXPORT inputStreamByteBufferAdapter : public seekableInputStream -{ public: inputStreamByteBufferAdapter(const byte_t* buffer, size_t length); @@ -62,4 +61,3 @@ private: #endif // VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/inputStreamPointerAdapter.cpp b/src/vmime/utility/inputStreamPointerAdapter.cpp index 6bf0461a..3f468d4f 100644 --- a/src/vmime/utility/inputStreamPointerAdapter.cpp +++ b/src/vmime/utility/inputStreamPointerAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,18 +29,20 @@ namespace utility { inputStreamPointerAdapter::inputStreamPointerAdapter(std::istream* is, const bool own) - : inputStreamAdapter(*is), m_stream(is), m_own(own) -{ + : inputStreamAdapter(*is), + m_stream(is), + m_own(own) { + } -inputStreamPointerAdapter::~inputStreamPointerAdapter() -{ - if (m_own) - delete (m_stream); +inputStreamPointerAdapter::~inputStreamPointerAdapter() { + + if (m_own) { + delete m_stream; + } } } // utility } // vmime - diff --git a/src/vmime/utility/inputStreamPointerAdapter.hpp b/src/vmime/utility/inputStreamPointerAdapter.hpp index 4fc606a9..e48f9ce4 100644 --- a/src/vmime/utility/inputStreamPointerAdapter.hpp +++ b/src/vmime/utility/inputStreamPointerAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,8 @@ namespace utility { /** An adapter class for pointer to C++ standard input stream. */ +class VMIME_EXPORT inputStreamPointerAdapter : public inputStreamAdapter { -class VMIME_EXPORT inputStreamPointerAdapter : public inputStreamAdapter -{ public: /** @param is input stream to wrap @@ -60,4 +59,3 @@ private: #endif // VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/inputStreamSocketAdapter.cpp b/src/vmime/utility/inputStreamSocketAdapter.cpp index d78855eb..515906bb 100644 --- a/src/vmime/utility/inputStreamSocketAdapter.cpp +++ b/src/vmime/utility/inputStreamSocketAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,41 +35,39 @@ namespace utility { inputStreamSocketAdapter::inputStreamSocketAdapter(net::socket& sok) - : m_socket(sok) -{ + : m_socket(sok) { + } -bool inputStreamSocketAdapter::eof() const -{ +bool inputStreamSocketAdapter::eof() const { + // Can't know... return false; } -void inputStreamSocketAdapter::reset() -{ +void inputStreamSocketAdapter::reset() { + // Not supported } -size_t inputStreamSocketAdapter::read - (byte_t* const data, const size_t count) -{ +size_t inputStreamSocketAdapter::read(byte_t* const data, const size_t count) { + return m_socket.receiveRaw(data, count); } -size_t inputStreamSocketAdapter::skip - (const size_t /* count */) -{ +size_t inputStreamSocketAdapter::skip(const size_t /* count */) { + // Not supported return 0; } -size_t inputStreamSocketAdapter::getBlockSize() -{ +size_t inputStreamSocketAdapter::getBlockSize() { + return m_socket.getBlockSize(); } @@ -79,4 +77,3 @@ size_t inputStreamSocketAdapter::getBlockSize() #endif // VMIME_HAVE_MESSAGING_FEATURES - diff --git a/src/vmime/utility/inputStreamSocketAdapter.hpp b/src/vmime/utility/inputStreamSocketAdapter.hpp index a990f628..1650037b 100644 --- a/src/vmime/utility/inputStreamSocketAdapter.hpp +++ b/src/vmime/utility/inputStreamSocketAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,9 +44,8 @@ namespace utility { /** An input stream that is connected to a socket. */ +class VMIME_EXPORT inputStreamSocketAdapter : public inputStream { -class VMIME_EXPORT inputStreamSocketAdapter : public inputStream -{ public: inputStreamSocketAdapter(net::socket& sok); @@ -74,4 +73,3 @@ private: #endif // VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/inputStreamStringAdapter.cpp b/src/vmime/utility/inputStreamStringAdapter.cpp index 9b897b97..bf09a9b8 100644 --- a/src/vmime/utility/inputStreamStringAdapter.cpp +++ b/src/vmime/utility/inputStreamStringAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,79 +29,91 @@ namespace utility { inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer) - : m_buffer(buffer), m_begin(0), m_end(buffer.length()), m_pos(0) -{ + : m_buffer(buffer), + m_begin(0), + m_end(buffer.length()), + m_pos(0) { + } -inputStreamStringAdapter::inputStreamStringAdapter(const string& buffer, - const size_t begin, const size_t end) - : m_buffer(buffer), m_begin(begin), m_end(end), m_pos(begin) -{ +inputStreamStringAdapter::inputStreamStringAdapter( + const string& buffer, + const size_t begin, + const size_t end +) + : m_buffer(buffer), + m_begin(begin), + m_end(end), + m_pos(begin) { + } -bool inputStreamStringAdapter::eof() const -{ - return (m_pos >= m_end); +bool inputStreamStringAdapter::eof() const { + + return m_pos >= m_end; } -void inputStreamStringAdapter::reset() -{ +void inputStreamStringAdapter::reset() { + m_pos = m_begin; } -size_t inputStreamStringAdapter::read - (byte_t* const data, const size_t count) -{ - if (m_pos + count >= m_end) - { +size_t inputStreamStringAdapter::read(byte_t* const data, const size_t count) { + + if (m_pos + count >= m_end) { + const size_t remaining = m_end - m_pos; std::copy(m_buffer.begin() + m_pos, m_buffer.end(), data); m_pos = m_end; - return (remaining); - } - else - { + + return remaining; + + } else { + std::copy(m_buffer.begin() + m_pos, m_buffer.begin() + m_pos + count, data); m_pos += count; - return (count); + + return count; } } -size_t inputStreamStringAdapter::skip(const size_t count) -{ - if (m_pos + count >= m_end) - { +size_t inputStreamStringAdapter::skip(const size_t count) { + + if (m_pos + count >= m_end) { + const size_t remaining = m_end - m_pos; m_pos = m_end; - return (remaining); - } - else - { + + return remaining; + + } else { + m_pos += count; - return (count); + + return count; } } -size_t inputStreamStringAdapter::getPosition() const -{ +size_t inputStreamStringAdapter::getPosition() const { + return m_pos - m_begin; } -void inputStreamStringAdapter::seek(const size_t pos) -{ - if (m_begin + pos <= m_end) +void inputStreamStringAdapter::seek(const size_t pos) { + + if (m_begin + pos <= m_end) { m_pos = m_begin + pos; + } } } // utility } // vmime - diff --git a/src/vmime/utility/inputStreamStringAdapter.hpp b/src/vmime/utility/inputStreamStringAdapter.hpp index 4ee597e6..2c2cbb84 100644 --- a/src/vmime/utility/inputStreamStringAdapter.hpp +++ b/src/vmime/utility/inputStreamStringAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An adapter class for string input. */ +class VMIME_EXPORT inputStreamStringAdapter : public seekableInputStream { -class VMIME_EXPORT inputStreamStringAdapter : public seekableInputStream -{ public: inputStreamStringAdapter(const string& buffer); @@ -65,4 +64,3 @@ private: #endif // VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/inputStreamStringProxyAdapter.cpp b/src/vmime/utility/inputStreamStringProxyAdapter.cpp index 5513de80..743e0d7f 100644 --- a/src/vmime/utility/inputStreamStringProxyAdapter.cpp +++ b/src/vmime/utility/inputStreamStringProxyAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,73 +30,75 @@ namespace utility { inputStreamStringProxyAdapter::inputStreamStringProxyAdapter(const stringProxy& buffer) - : m_buffer(buffer), m_pos(0) -{ + : m_buffer(buffer), + m_pos(0) { + } -bool inputStreamStringProxyAdapter::eof() const -{ - return (m_pos >= m_buffer.length()); +bool inputStreamStringProxyAdapter::eof() const { + + return m_pos >= m_buffer.length(); } -void inputStreamStringProxyAdapter::reset() -{ +void inputStreamStringProxyAdapter::reset() { + m_pos = 0; } -size_t inputStreamStringProxyAdapter::read - (byte_t* const data, const size_t count) -{ +size_t inputStreamStringProxyAdapter::read(byte_t* const data, const size_t count) { + const size_t remaining = m_buffer.length() - m_pos; - if (count > remaining) - { + if (count > remaining) { + std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_end(), data); m_pos = m_buffer.length(); - return (remaining); - } - else - { + + return remaining; + + } else { + std::copy(m_buffer.it_begin() + m_pos, m_buffer.it_begin() + m_pos + count, data); m_pos += count; - return (count); + + return count; } } -size_t inputStreamStringProxyAdapter::skip(const size_t count) -{ +size_t inputStreamStringProxyAdapter::skip(const size_t count) { + const size_t remaining = m_buffer.length() - m_pos; - if (count > remaining) - { + if (count > remaining) { + m_pos = m_buffer.length(); - return (remaining); - } - else - { + return remaining; + + } else { + m_pos += count; - return (count); + return count; } } -size_t inputStreamStringProxyAdapter::getPosition() const -{ +size_t inputStreamStringProxyAdapter::getPosition() const { + return m_pos; } -void inputStreamStringProxyAdapter::seek(const size_t pos) -{ - if (pos <= m_buffer.length()) +void inputStreamStringProxyAdapter::seek(const size_t pos) { + + if (pos <= m_buffer.length()) { m_pos = pos; + } } } // utility } // vmime - diff --git a/src/vmime/utility/inputStreamStringProxyAdapter.hpp b/src/vmime/utility/inputStreamStringProxyAdapter.hpp index 02dc2056..4d0496b1 100644 --- a/src/vmime/utility/inputStreamStringProxyAdapter.hpp +++ b/src/vmime/utility/inputStreamStringProxyAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,8 @@ class stringProxy; /** An adapter class for stringProxy input. */ +class VMIME_EXPORT inputStreamStringProxyAdapter : public seekableInputStream { -class VMIME_EXPORT inputStreamStringProxyAdapter : public seekableInputStream -{ public: /** @param buffer stringProxy object to wrap @@ -67,4 +66,3 @@ private: #endif // VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/outputStream.cpp b/src/vmime/utility/outputStream.cpp index 070e28c5..b07fb073 100644 --- a/src/vmime/utility/outputStream.cpp +++ b/src/vmime/utility/outputStream.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,18 +28,17 @@ namespace vmime { namespace utility { -void outputStream::write(const byte_t* const data, const size_t count) -{ +void outputStream::write(const byte_t* const data, const size_t count) { + writeImpl(data, count); } -void outputStream::write(const char* const data, const size_t count) -{ +void outputStream::write(const char* const data, const size_t count) { + writeImpl(reinterpret_cast (data), count); } } // utility } // vmime - diff --git a/src/vmime/utility/outputStream.hpp b/src/vmime/utility/outputStream.hpp index 62ee7336..318c1dd4 100644 --- a/src/vmime/utility/outputStream.hpp +++ b/src/vmime/utility/outputStream.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,9 +39,8 @@ namespace utility { /** Simple output stream. */ +class VMIME_EXPORT outputStream : public stream { -class VMIME_EXPORT outputStream : public stream -{ public: /** Write data to the stream. @@ -65,8 +64,8 @@ public: * null (value is induced by compiler) */ template - void write(const char (&data)[N]) - { + void write(const char (&data)[N]) { + write(data, N - 1); } @@ -95,27 +94,27 @@ VMIME_EXPORT outputStream& operator<<(outputStream& os, const byte_t c); #if defined(_MSC_VER) && (_MSC_VER <= 1200) // Internal compiler error with VC++6 -inline outputStream& operator<<(outputStream& os, const char* str) -{ +inline outputStream& operator<<(outputStream& os, const char* str) { + os.write(reinterpret_cast (str), ::strlen(str)); - return (os); + return os; } #else template -outputStream& operator<<(outputStream& os, const char (&str)[N]) -{ +outputStream& operator<<(outputStream& os, const char (&str)[N]) { + os.write(reinterpret_cast (str), N - 1); - return (os); + return os; } #endif // defined(_MSC_VER) && (_MSC_VER <= 1200) template -outputStream& operator<<(outputStream& os, const T& t) -{ +outputStream& operator<<(outputStream& os, const T& t) { + std::ostringstream oss; oss.imbue(std::locale::classic()); // no formatting @@ -123,14 +122,12 @@ outputStream& operator<<(outputStream& os, const T& t) os << oss.str(); - return (os); + return os; } - } // utility } // vmime #endif // VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED - diff --git a/src/vmime/utility/outputStreamAdapter.cpp b/src/vmime/utility/outputStreamAdapter.cpp index ed90c7d3..74556919 100644 --- a/src/vmime/utility/outputStreamAdapter.cpp +++ b/src/vmime/utility/outputStreamAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,21 +29,20 @@ namespace utility { outputStreamAdapter::outputStreamAdapter(std::ostream& os) - : m_stream(os) -{ + : m_stream(os) { + } -void outputStreamAdapter::writeImpl - (const byte_t* const data, const size_t count) -{ +void outputStreamAdapter::writeImpl(const byte_t* const data, const size_t count) { + m_stream.exceptions(std::ios_base::badbit); m_stream.write(reinterpret_cast (data), count); } -void outputStreamAdapter::flush() -{ +void outputStreamAdapter::flush() { + m_stream.exceptions(std::ios_base::badbit); m_stream.flush(); } @@ -51,4 +50,3 @@ void outputStreamAdapter::flush() } // utility } // vmime - diff --git a/src/vmime/utility/outputStreamAdapter.hpp b/src/vmime/utility/outputStreamAdapter.hpp index f0125584..35c5cdea 100644 --- a/src/vmime/utility/outputStreamAdapter.hpp +++ b/src/vmime/utility/outputStreamAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,8 @@ namespace utility { /** An adapter class for C++ standard output streams. */ +class VMIME_EXPORT outputStreamAdapter : public outputStream { -class VMIME_EXPORT outputStreamAdapter : public outputStream -{ public: /** @param os output stream to wrap @@ -62,4 +61,3 @@ private: #endif // VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/outputStreamByteArrayAdapter.cpp b/src/vmime/utility/outputStreamByteArrayAdapter.cpp index 1bed735b..a38bd799 100644 --- a/src/vmime/utility/outputStreamByteArrayAdapter.cpp +++ b/src/vmime/utility/outputStreamByteArrayAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,24 +29,22 @@ namespace utility { outputStreamByteArrayAdapter::outputStreamByteArrayAdapter(byteArray& array) - : m_array(array) -{ + : m_array(array) { + } -void outputStreamByteArrayAdapter::writeImpl - (const byte_t* const data, const size_t count) -{ +void outputStreamByteArrayAdapter::writeImpl(const byte_t* const data, const size_t count) { + m_array.insert(m_array.end(), data, data + count); } -void outputStreamByteArrayAdapter::flush() -{ +void outputStreamByteArrayAdapter::flush() { + // Do nothing } } // utility } // vmime - diff --git a/src/vmime/utility/outputStreamByteArrayAdapter.hpp b/src/vmime/utility/outputStreamByteArrayAdapter.hpp index a2178a9c..f36ff9c2 100644 --- a/src/vmime/utility/outputStreamByteArrayAdapter.hpp +++ b/src/vmime/utility/outputStreamByteArrayAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An adapter class for byte array output. */ +class VMIME_EXPORT outputStreamByteArrayAdapter : public outputStream { -class VMIME_EXPORT outputStreamByteArrayAdapter : public outputStream -{ public: outputStreamByteArrayAdapter(byteArray& array); @@ -58,4 +57,3 @@ private: #endif // VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/outputStreamSocketAdapter.cpp b/src/vmime/utility/outputStreamSocketAdapter.cpp index 03194497..cd82c447 100644 --- a/src/vmime/utility/outputStreamSocketAdapter.cpp +++ b/src/vmime/utility/outputStreamSocketAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,34 +35,31 @@ namespace utility { outputStreamSocketAdapter::outputStreamSocketAdapter(net::socket& sok) - : m_socket(sok) -{ + : m_socket(sok) { + } -void outputStreamSocketAdapter::writeImpl - (const byte_t* const data, const size_t count) -{ +void outputStreamSocketAdapter::writeImpl(const byte_t* const data, const size_t count) { + m_socket.sendRaw(data, count); } -void outputStreamSocketAdapter::flush() -{ +void outputStreamSocketAdapter::flush() { + // Do nothing } -size_t outputStreamSocketAdapter::getBlockSize() -{ +size_t outputStreamSocketAdapter::getBlockSize() { + return m_socket.getBlockSize(); } - } // utility } // vmime #endif // VMIME_HAVE_MESSAGING_FEATURES - diff --git a/src/vmime/utility/outputStreamSocketAdapter.hpp b/src/vmime/utility/outputStreamSocketAdapter.hpp index 6cd00626..4fb199ba 100644 --- a/src/vmime/utility/outputStreamSocketAdapter.hpp +++ b/src/vmime/utility/outputStreamSocketAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,9 +44,8 @@ namespace utility { /** An output stream that is connected to a socket. */ +class VMIME_EXPORT outputStreamSocketAdapter : public outputStream { -class VMIME_EXPORT outputStreamSocketAdapter : public outputStream -{ public: outputStreamSocketAdapter(net::socket& sok); @@ -75,4 +74,3 @@ private: #endif // VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/outputStreamStringAdapter.cpp b/src/vmime/utility/outputStreamStringAdapter.cpp index 7105480c..12c809c4 100644 --- a/src/vmime/utility/outputStreamStringAdapter.cpp +++ b/src/vmime/utility/outputStreamStringAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,24 +31,22 @@ namespace utility { outputStreamStringAdapter::outputStreamStringAdapter(string& buffer) - : m_buffer(buffer) -{ + : m_buffer(buffer) { + } -void outputStreamStringAdapter::writeImpl - (const byte_t* const data, const size_t count) -{ +void outputStreamStringAdapter::writeImpl(const byte_t* const data, const size_t count) { + vmime::utility::stringUtils::appendBytesToString(m_buffer, data, count); } -void outputStreamStringAdapter::flush() -{ +void outputStreamStringAdapter::flush() { + // Do nothing } } // utility } // vmime - diff --git a/src/vmime/utility/outputStreamStringAdapter.hpp b/src/vmime/utility/outputStreamStringAdapter.hpp index 89516827..a29e2cb1 100644 --- a/src/vmime/utility/outputStreamStringAdapter.hpp +++ b/src/vmime/utility/outputStreamStringAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An adapter class for string output. */ +class VMIME_EXPORT outputStreamStringAdapter : public outputStream { -class VMIME_EXPORT outputStreamStringAdapter : public outputStream -{ public: outputStreamStringAdapter(string& buffer); @@ -58,4 +57,3 @@ private: #endif // VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/parserInputStreamAdapter.cpp b/src/vmime/utility/parserInputStreamAdapter.cpp index ee6a58dd..98bbe607 100644 --- a/src/vmime/utility/parserInputStreamAdapter.cpp +++ b/src/vmime/utility/parserInputStreamAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,44 +29,43 @@ namespace utility { parserInputStreamAdapter::parserInputStreamAdapter(const shared_ptr & stream) - : m_stream(stream) -{ + : m_stream(stream) { + } -bool parserInputStreamAdapter::eof() const -{ +bool parserInputStreamAdapter::eof() const { + return m_stream->eof(); } -void parserInputStreamAdapter::reset() -{ +void parserInputStreamAdapter::reset() { + m_stream->reset(); } -size_t parserInputStreamAdapter::read - (byte_t* const data, const size_t count) -{ +size_t parserInputStreamAdapter::read(byte_t* const data, const size_t count) { + return m_stream->read(data, count); } -shared_ptr parserInputStreamAdapter::getUnderlyingStream() -{ +shared_ptr parserInputStreamAdapter::getUnderlyingStream() { + return m_stream; } -const string parserInputStreamAdapter::extract(const size_t begin, const size_t end) const -{ +const string parserInputStreamAdapter::extract(const size_t begin, const size_t end) const { + const size_t initialPos = m_stream->getPosition(); byte_t *buffer = NULL; - try - { + try { + buffer = new byte_t[end - begin + 1]; m_stream->seek(begin); @@ -80,9 +79,9 @@ const string parserInputStreamAdapter::extract(const size_t begin, const size_t delete [] buffer; return str; - } - catch (...) - { + + } catch (...) { + delete [] buffer; m_stream->seek(initialPos); @@ -91,21 +90,24 @@ const string parserInputStreamAdapter::extract(const size_t begin, const size_t } -size_t parserInputStreamAdapter::findNext - (const string& token, const size_t startPosition) -{ +size_t parserInputStreamAdapter::findNext( + const string& token, + const size_t startPosition +) { + static const unsigned int BUFFER_SIZE = 4096; // Token must not be longer than BUFFER_SIZE/2 - if (token.empty() || token.length() > BUFFER_SIZE / 2) + if (token.empty() || token.length() > BUFFER_SIZE / 2) { return npos; + } const size_t initialPos = getPosition(); seek(startPosition); - try - { + try { + byte_t findBuffer[BUFFER_SIZE]; byte_t* findBuffer1 = findBuffer; byte_t* findBuffer2 = findBuffer + (BUFFER_SIZE / 2); @@ -118,19 +120,20 @@ size_t parserInputStreamAdapter::findNext // Fill in initial buffer findBufferLen = read(findBuffer, BUFFER_SIZE); - while (findBufferLen != 0) - { + while (findBufferLen != 0) { + // Find token for (byte_t *begin = findBuffer, *end = findBuffer + findBufferLen - token.length() ; - begin <= end ; ++begin) - { + begin <= end ; ++begin) { + if (begin[0] == token[0] && (token.length() == 1 || memcmp(static_cast (&begin[1]), static_cast (token.data() + 1), - token.length() - 1) == 0)) - { + token.length() - 1) == 0)) { + seek(initialPos); + return startPosition + findBufferOffset + (begin - findBuffer); } } @@ -139,16 +142,17 @@ size_t parserInputStreamAdapter::findNext memcpy(findBuffer1, findBuffer2, (BUFFER_SIZE / 2)); // Read more bytes - if (findBufferLen < BUFFER_SIZE && (eof() || isEOF)) - { + if (findBufferLen < BUFFER_SIZE && (eof() || isEOF)) { + break; - } - else - { + + } else { + const size_t bytesRead = read(findBuffer2, BUFFER_SIZE / 2); - if (bytesRead == 0) + if (bytesRead == 0) { isEOF = true; + } findBufferLen = (BUFFER_SIZE / 2) + bytesRead; findBufferOffset += (BUFFER_SIZE / 2); @@ -156,9 +160,9 @@ size_t parserInputStreamAdapter::findNext } seek(initialPos); - } - catch (...) - { + + } catch (...) { + seek(initialPos); throw; } @@ -169,4 +173,3 @@ size_t parserInputStreamAdapter::findNext } // utility } // vmime - diff --git a/src/vmime/utility/parserInputStreamAdapter.hpp b/src/vmime/utility/parserInputStreamAdapter.hpp index f6e360cb..e448d29c 100644 --- a/src/vmime/utility/parserInputStreamAdapter.hpp +++ b/src/vmime/utility/parserInputStreamAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,8 @@ namespace utility { /** An adapter class used for parsing from an input stream. */ +class VMIME_EXPORT parserInputStreamAdapter : public seekableInputStream { -class VMIME_EXPORT parserInputStreamAdapter : public seekableInputStream -{ public: /** @param stream input stream to wrap @@ -51,18 +50,18 @@ public: void reset(); size_t read(byte_t* const data, const size_t count); - void seek(const size_t pos) - { + void seek(const size_t pos) { + m_stream->seek(pos); } - size_t skip(const size_t count) - { + size_t skip(const size_t count) { + return m_stream->skip(count); } - size_t getPosition() const - { + size_t getPosition() const { + return m_stream->getPosition(); } @@ -71,21 +70,21 @@ public: * * @return byte at the current position */ - byte_t peekByte() const - { + byte_t peekByte() const { + const size_t initialPos = m_stream->getPosition(); - try - { + try { + byte_t buffer[1]; const size_t readBytes = m_stream->read(buffer, 1); m_stream->seek(initialPos); return (readBytes == 1 ? buffer[0] : static_cast (0)); - } - catch (...) - { + + } catch (...) { + m_stream->seek(initialPos); throw; } @@ -96,12 +95,12 @@ public: * * @return byte at the current position */ - byte_t getByte() - { + byte_t getByte() { + byte_t buffer[1]; const size_t readBytes = m_stream->read(buffer, 1); - return (readBytes == 1 ? buffer[0] : static_cast (0)); + return readBytes == 1 ? buffer[0] : static_cast (0); } /** Check whether the bytes following the current position match @@ -112,22 +111,21 @@ public: * @return true if the next bytes match the pattern, false otherwise */ template - bool matchBytes(const T* bytes, const size_t length) const - { + bool matchBytes(const T* bytes, const size_t length) const { + const size_t initialPos = m_stream->getPosition(); - try - { + try { + byte_t buffer[32]; const size_t readBytes = m_stream->read(buffer, length); m_stream->seek(initialPos); - return readBytes == length && - ::memcmp(bytes, buffer, length) == 0; - } - catch (...) - { + return readBytes == length && ::memcmp(bytes, buffer, length) == 0; + + } catch (...) { + m_stream->seek(initialPos); throw; } @@ -145,13 +143,14 @@ public: * @return number of bytes skipped */ template - size_t skipIf(PREDICATE pred, const size_t endPosition) - { + size_t skipIf(PREDICATE pred, const size_t endPosition) { + const size_t initialPos = getPosition(); size_t pos = initialPos; - while (!m_stream->eof() && pos < endPosition && pred(getByte())) + while (!m_stream->eof() && pos < endPosition && pred(getByte())) { ++pos; + } m_stream->seek(pos); @@ -171,4 +170,3 @@ private: #endif // VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/path.cpp b/src/vmime/utility/path.cpp index 7ce028ff..0c70f116 100644 --- a/src/vmime/utility/path.cpp +++ b/src/vmime/utility/path.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,276 +30,288 @@ namespace vmime { namespace utility { -path::path() -{ +path::path() { + } -path::path(const component& c) -{ +path::path(const component& c) { + m_list.push_back(c); } path::path(const path& p) - : object() -{ + : object() { + m_list.resize(p.m_list.size()); std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin()); } -path::path(const string& s) -{ +path::path(const string& s) { + m_list.push_back(component(s)); } -path path::operator/(const path& p) const -{ +path path::operator/(const path& p) const { + path pr(*this); pr /= p; - return (pr); + return pr; } -path path::operator/(const component& c) const -{ +path path::operator/(const component& c) const { + path pr(*this); pr /= c; - return (pr); + return pr; } -path& path::operator/=(const path& p) -{ +path& path::operator/=(const path& p) { + const list::size_type size = m_list.size(); m_list.resize(size + p.m_list.size()); std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin() + size); - return (*this); + return *this; } -path& path::operator/=(const component& c) -{ +path& path::operator/=(const component& c) { + m_list.push_back(c); - return (*this); + return *this; } -path path::getParent() const -{ +path path::getParent() const { + path p; - if (!isEmpty()) - { + if (!isEmpty()) { p.m_list.resize(m_list.size() - 1); std::copy(m_list.begin(), m_list.end() - 1, p.m_list.begin()); } - return (p); + return p; } -path& path::operator=(const path& p) -{ +path& path::operator=(const path& p) { + m_list.resize(p.m_list.size()); std::copy(p.m_list.begin(), p.m_list.end(), m_list.begin()); - return (*this); + return *this; } -path& path::operator=(const component& c) -{ +path& path::operator=(const component& c) { + m_list.resize(1); m_list[0] = c; - return (*this); + return *this; } -bool path::operator==(const path& p) const -{ - if (m_list.size() != p.m_list.size()) +bool path::operator==(const path& p) const { + + if (m_list.size() != p.m_list.size()) { return (false); + } list::const_iterator i = m_list.begin(); list::const_iterator j = p.m_list.begin(); bool equal = true; - for ( ; equal && i != m_list.end() ; ++i, ++j) + for ( ; equal && i != m_list.end() ; ++i, ++j) { equal = ((*i).isEquivalent(*j)); + } - return (equal); + return equal; } -bool path::operator!=(const path& p) const -{ - return (!(*this == p)); +bool path::operator!=(const path& p) const { + + return !(*this == p); } -bool path::isEmpty() const -{ - return (m_list.empty()); +bool path::isEmpty() const { + + return m_list.empty(); } -bool path::isRoot() const -{ - return (m_list.empty()); +bool path::isRoot() const { + + return m_list.empty(); } -const path::component path::getLastComponent() const -{ - return (m_list[m_list.size() - 1]); +const path::component path::getLastComponent() const { + + return m_list[m_list.size() - 1]; } -path::component& path::getLastComponent() -{ - return (m_list[m_list.size() - 1]); +path::component& path::getLastComponent() { + + return m_list[m_list.size() - 1]; } -size_t path::getSize() const -{ - return (m_list.size()); +size_t path::getSize() const { + + return m_list.size(); } -const path::component& path::operator[](const size_t x) const -{ - return (m_list[x]); +const path::component& path::operator[](const size_t x) const { + + return m_list[x]; } -path::component& path::operator[](const size_t x) -{ - return (m_list[x]); +path::component& path::operator[](const size_t x) { + + return m_list[x]; } -bool path::isDirectParentOf(const path& p) const -{ - if (p.getSize() != getSize() + 1) - return (false); +bool path::isDirectParentOf(const path& p) const { + + if (p.getSize() != getSize() + 1) { + return false; + } bool equal = true; - for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) + for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) { equal = (m_list[i].isEquivalent(p.m_list[i])); + } - return (equal); + return equal; } -bool path::isParentOf(const path& p) const -{ - if (p.getSize() < getSize() + 1) - return (false); +bool path::isParentOf(const path& p) const { + + if (p.getSize() < getSize() + 1) { + return false; + } bool equal = true; - for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) + for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) { equal = (m_list[i].isEquivalent(p.m_list[i])); + } - return (equal); + return equal; } -void path::renameParent(const path& oldPath, const path& newPath) -{ - if (isEmpty() || oldPath.getSize() > getSize()) +void path::renameParent(const path& oldPath, const path& newPath) { + + if (isEmpty() || oldPath.getSize() > getSize()) { return; + } bool equal = true; list::size_type i; - for (i = 0 ; equal && i < oldPath.m_list.size() ; ++i) + for (i = 0 ; equal && i < oldPath.m_list.size() ; ++i) { equal = (m_list[i].isEquivalent(oldPath.m_list[i])); + } if (i != oldPath.m_list.size()) return; list newList; - for (list::size_type j = 0 ; j < newPath.m_list.size() ; ++j) + for (list::size_type j = 0 ; j < newPath.m_list.size() ; ++j) { newList.push_back(newPath.m_list[j]); + } - for (list::size_type j = i ; j < m_list.size() ; ++j) + for (list::size_type j = i ; j < m_list.size() ; ++j) { newList.push_back(m_list[j]); + } m_list.resize(newList.size()); std::copy(newList.begin(), newList.end(), m_list.begin()); } -void path::appendComponent(const path::component& c) -{ +void path::appendComponent(const path::component& c) { + m_list.push_back(c); } -const path::component& path::getComponentAt(const size_t pos) const -{ - return (m_list[pos]); +const path::component& path::getComponentAt(const size_t pos) const { + + return m_list[pos]; } -path::component& path::getComponentAt(const size_t pos) -{ - return (m_list[pos]); +path::component& path::getComponentAt(const size_t pos) { + + return m_list[pos]; } // static -path path::fromString(const string& str, const string& sep, const charset& cset) -{ +path path::fromString(const string& str, const string& sep, const charset& cset) { + path p; size_t start = 0; size_t end = 0; - do - { + do { + end = str.find(sep, start); string comp; - if (end == string::npos) + if (end == string::npos) { comp = str.substr(start); - else + } else { comp = str.substr(start, end - start); + } // Skip leading or trailing separators - if (comp.length()) + if (comp.length()) { p.appendComponent(component(comp, cset)); + } start = end + 1; - } - while (end != string::npos); + + } while (end != string::npos); return p; } -const string path::toString(const string& sep, const charset& cset) const -{ +const string path::toString(const string& sep, const charset& cset) const { + string str; - for (size_t i = 0 ; i < m_list.size() ; ++i) - { - if (i != 0) + for (size_t i = 0 ; i < m_list.size() ; ++i) { + + if (i != 0) { str += sep; + } str += m_list[i].getConvertedText(cset); } diff --git a/src/vmime/utility/path.hpp b/src/vmime/utility/path.hpp index 310fa24b..f1f15148 100644 --- a/src/vmime/utility/path.hpp +++ b/src/vmime/utility/path.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,8 @@ namespace utility { /** Abstract representation of a path (filesystem, mailbox, etc). */ +class VMIME_EXPORT path : public object { -class VMIME_EXPORT path : public object -{ public: typedef vmime::word component; diff --git a/src/vmime/utility/progressListener.cpp b/src/vmime/utility/progressListener.cpp index 6764c563..cc4969c6 100644 --- a/src/vmime/utility/progressListener.cpp +++ b/src/vmime/utility/progressListener.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,38 +30,44 @@ namespace utility { // progressListenerSizeAdapter -progressListenerSizeAdapter::progressListenerSizeAdapter - (progressListener* list, const size_t total) - : m_wrapped(list), m_total(total) -{ +progressListenerSizeAdapter::progressListenerSizeAdapter( + progressListener* list, + const size_t total +) + : m_wrapped(list), + m_total(total) { + } -void progressListenerSizeAdapter::start(const size_t predictedTotal) -{ - if (m_wrapped) +void progressListenerSizeAdapter::start(const size_t predictedTotal) { + + if (m_wrapped) { m_wrapped->start(predictedTotal); + } } -void progressListenerSizeAdapter::progress(const size_t current, const size_t currentTotal) -{ - if (m_wrapped) - { - if (currentTotal > m_total) +void progressListenerSizeAdapter::progress(const size_t current, const size_t currentTotal) { + + if (m_wrapped) { + + if (currentTotal > m_total) { m_total = currentTotal; + } m_wrapped->progress(current, m_total); } } -void progressListenerSizeAdapter::stop(const size_t total) -{ - if (m_wrapped) - { - if (total > m_total) +void progressListenerSizeAdapter::stop(const size_t total) { + + if (m_wrapped) { + + if (total > m_total) { m_total = total; + } m_wrapped->stop(m_total); } @@ -70,4 +76,3 @@ void progressListenerSizeAdapter::stop(const size_t total) } // utility } // vmime - diff --git a/src/vmime/utility/progressListener.hpp b/src/vmime/utility/progressListener.hpp index e86fb808..18b4e4dd 100644 --- a/src/vmime/utility/progressListener.hpp +++ b/src/vmime/utility/progressListener.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,9 +36,8 @@ namespace utility { /** An interface to implement if you want to be notified * of a state of progress by some objects. */ +class VMIME_EXPORT progressListener { -class VMIME_EXPORT progressListener -{ protected: virtual ~progressListener() { } @@ -71,9 +70,8 @@ public: /** A progress listener used when total size is known by the * receiver, but not by the notifier. */ +class VMIME_EXPORT progressListenerSizeAdapter : public progressListener { -class VMIME_EXPORT progressListenerSizeAdapter : public progressListener -{ public: /** Construct a new progressListenerSizeAdapter object. @@ -99,4 +97,3 @@ private: #endif // VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED - diff --git a/src/vmime/utility/random.cpp b/src/vmime/utility/random.cpp index 97d12ddc..055122b5 100644 --- a/src/vmime/utility/random.cpp +++ b/src/vmime/utility/random.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,19 +31,20 @@ namespace vmime { namespace utility { -static unsigned int getRandomSeed() -{ +static unsigned int getRandomSeed() { + unsigned int seed; - platform::getHandler()->generateRandomBytes - (reinterpret_cast (&seed), sizeof(seed)); + platform::getHandler()->generateRandomBytes( + reinterpret_cast (&seed), sizeof(seed) + ); return seed; } -unsigned int random::getNext() -{ +unsigned int random::getNext() { + static unsigned int next = getRandomSeed(); // Park and Miller's minimal standard generator: @@ -54,35 +55,34 @@ unsigned int random::getNext() } -unsigned int random::getTime() -{ +unsigned int random::getTime() { + return static_cast ((platform::getHandler()->getUnixTime())); } -unsigned int random::getProcess() -{ - return (platform::getHandler()->getProcessId()); +unsigned int random::getProcess() { + + return platform::getHandler()->getProcessId(); } -const string random::getString(const size_t length, const string& randomChars) -{ +const string random::getString(const size_t length, const string& randomChars) { + string res; res.resize(length); const unsigned int x = static_cast (randomChars.length()); size_t c = 0; - while (c < length) - { - for (unsigned int n = random::getNext() ; n != 0 && c < length ; n /= x) - { + while (c < length) { + + for (unsigned int n = random::getNext() ; n != 0 && c < length ; n /= x) { res[c++] = randomChars[n % x]; } } - return (res); + return res; } diff --git a/src/vmime/utility/random.hpp b/src/vmime/utility/random.hpp index b667c3a2..21f4949e 100644 --- a/src/vmime/utility/random.hpp +++ b/src/vmime/utility/random.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** Pseudo-random number generator. */ +class random { -class random -{ public: /** Return a new random number. @@ -65,8 +64,10 @@ public: * @param randomChars list of characters to use * @return random string */ - static const string getString(const size_t length, const string& randomChars - = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + static const string getString( + const size_t length, + const string& randomChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + ); }; diff --git a/src/vmime/utility/seekableInputStream.hpp b/src/vmime/utility/seekableInputStream.hpp index f56af9c4..181e904a 100644 --- a/src/vmime/utility/seekableInputStream.hpp +++ b/src/vmime/utility/seekableInputStream.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An input stream that allows seeking within the input. */ +class VMIME_EXPORT seekableInputStream : public inputStream { -class VMIME_EXPORT seekableInputStream : public inputStream -{ public: /** Returns the current position in this stream. @@ -61,4 +60,3 @@ public: #endif // VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED - diff --git a/src/vmime/utility/seekableInputStreamRegionAdapter.cpp b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp index 6306d3dc..32723661 100644 --- a/src/vmime/utility/seekableInputStreamRegionAdapter.cpp +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,39 +28,44 @@ namespace vmime { namespace utility { -seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter - (const shared_ptr & stream, const size_t begin, const size_t length) - : m_stream(stream), m_begin(begin), m_length(length), m_position(0) -{ +seekableInputStreamRegionAdapter::seekableInputStreamRegionAdapter( + const shared_ptr & stream, + const size_t begin, + const size_t length +) + : m_stream(stream), + m_begin(begin), + m_length(length), + m_position(0) { + } -bool seekableInputStreamRegionAdapter::eof() const -{ +bool seekableInputStreamRegionAdapter::eof() const { + return m_position >= m_length; } -void seekableInputStreamRegionAdapter::reset() -{ +void seekableInputStreamRegionAdapter::reset() { + m_position = 0; } -size_t seekableInputStreamRegionAdapter::read - (byte_t* const data, const size_t count) -{ +size_t seekableInputStreamRegionAdapter::read(byte_t* const data, const size_t count) { + m_stream->seek(m_begin + m_position); size_t readBytes = 0; - if (m_position + count >= m_length) - { + if (m_position + count >= m_length) { + const size_t remaining = m_length - m_position; readBytes = m_stream->read(data, remaining); - } - else - { + + } else { + readBytes = m_stream->read(data, count); } @@ -70,37 +75,37 @@ size_t seekableInputStreamRegionAdapter::read } -size_t seekableInputStreamRegionAdapter::skip(const size_t count) -{ - if (m_position + count >= m_length) - { +size_t seekableInputStreamRegionAdapter::skip(const size_t count) { + + if (m_position + count >= m_length) { + const size_t remaining = m_length - m_position; m_position += remaining; return remaining; - } - else - { + + } else { + m_position += count; return count; } } -size_t seekableInputStreamRegionAdapter::getPosition() const -{ +size_t seekableInputStreamRegionAdapter::getPosition() const { + return m_position; } -void seekableInputStreamRegionAdapter::seek(const size_t pos) -{ - if (pos > m_length) +void seekableInputStreamRegionAdapter::seek(const size_t pos) { + + if (pos > m_length) { m_position = m_length; - else + } else { m_position = pos; + } } } // utility } // vmime - diff --git a/src/vmime/utility/seekableInputStreamRegionAdapter.hpp b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp index 70ab8ff3..8406b29e 100644 --- a/src/vmime/utility/seekableInputStreamRegionAdapter.hpp +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,8 @@ namespace utility { /** An adapter for reading a limited region of a seekable input stream. */ +class VMIME_EXPORT seekableInputStreamRegionAdapter : public seekableInputStream { -class VMIME_EXPORT seekableInputStreamRegionAdapter : public seekableInputStream -{ public: /** Creates a new adapter for a seekableInputStream. @@ -45,8 +44,11 @@ public: * @param begin start position in source stream * @param length region length in source stream */ - seekableInputStreamRegionAdapter(const shared_ptr & stream, - const size_t begin, const size_t length); + seekableInputStreamRegionAdapter( + const shared_ptr & stream, + const size_t begin, + const size_t length + ); bool eof() const; void reset(); @@ -69,4 +71,3 @@ private: #endif // VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED - diff --git a/src/vmime/utility/stream.cpp b/src/vmime/utility/stream.cpp index 232b23c7..96f99cbb 100644 --- a/src/vmime/utility/stream.cpp +++ b/src/vmime/utility/stream.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,12 +29,11 @@ namespace vmime { namespace utility { -size_t stream::getBlockSize() -{ +size_t stream::getBlockSize() { + return 32768; // 32 KB } } // utility } // vmime - diff --git a/src/vmime/utility/stream.hpp b/src/vmime/utility/stream.hpp index 980a2407..9aa13923 100644 --- a/src/vmime/utility/stream.hpp +++ b/src/vmime/utility/stream.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,12 +36,10 @@ namespace vmime { namespace utility { - /** Base class for input/output stream. */ +class VMIME_EXPORT stream : public object, private noncopyable { -class VMIME_EXPORT stream : public object, private noncopyable -{ public: virtual ~stream() { } diff --git a/src/vmime/utility/streamUtils.cpp b/src/vmime/utility/streamUtils.cpp index f3cc69ef..793973c2 100644 --- a/src/vmime/utility/streamUtils.cpp +++ b/src/vmime/utility/streamUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,29 +32,33 @@ namespace vmime { namespace utility { -outputStream& operator<<(outputStream& os, const byte_t c) -{ +outputStream& operator<<(outputStream& os, const byte_t c) { + os.write(&c, 1); - return (os); + return os; } -outputStream& operator<<(outputStream& os, const string& str) -{ +outputStream& operator<<(outputStream& os, const string& str) { + os.write(str.data(), str.length()); - return (os); + return os; } -size_t bufferedStreamCopy(inputStream& is, outputStream& os) -{ +size_t bufferedStreamCopy(inputStream& is, outputStream& os) { + return bufferedStreamCopy(is, os, 0, NULL); } -size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, - const size_t start, const size_t length) -{ +size_t bufferedStreamCopyRange( + inputStream& is, + outputStream& os, + const size_t start, + const size_t length +) { + const size_t blockSize = std::min(is.getBlockSize(), os.getBlockSize()); @@ -65,13 +69,12 @@ size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, byte_t* buffer = &vbuffer.front(); size_t total = 0; - while (!is.eof() && total < length) - { + while (!is.eof() && total < length) { + const size_t remaining = std::min(length - total, blockSize); const size_t read = is.read(buffer, remaining); - if (read != 0) - { + if (read != 0) { os.write(buffer, read); total += read; } @@ -81,9 +84,13 @@ size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, } -size_t bufferedStreamCopy(inputStream& is, outputStream& os, - const size_t length, progressListener* progress) -{ +size_t bufferedStreamCopy( + inputStream& is, + outputStream& os, + const size_t length, + progressListener* progress +) { + const size_t blockSize = std::min(is.getBlockSize(), os.getBlockSize()); @@ -92,30 +99,32 @@ size_t bufferedStreamCopy(inputStream& is, outputStream& os, byte_t* buffer = &vbuffer.front(); size_t total = 0; - if (progress != NULL) + if (progress != NULL) { progress->start(length); + } + + while (!is.eof()) { - while (!is.eof()) - { const size_t read = is.read(buffer, blockSize); - if (read != 0) - { + if (read != 0) { + os.write(buffer, read); total += read; - if (progress != NULL) + if (progress != NULL) { progress->progress(total, std::max(total, length)); + } } } - if (progress != NULL) + if (progress != NULL) { progress->stop(total); + } - return (total); + return total; } } // utility } // vmime - diff --git a/src/vmime/utility/streamUtils.hpp b/src/vmime/utility/streamUtils.hpp index 406b6b64..5d81fbe2 100644 --- a/src/vmime/utility/streamUtils.hpp +++ b/src/vmime/utility/streamUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,7 +41,6 @@ namespace utility { * @param os output stream (destination for data) * @return number of bytes copied */ - VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os); /** Copy data from one stream into another stream using a buffered method @@ -53,9 +52,12 @@ VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os); * @param length maximum number of bytes to copy * @return number of bytes copied */ - -VMIME_EXPORT size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, - const size_t start, const size_t length); +VMIME_EXPORT size_t bufferedStreamCopyRange( + inputStream& is, + outputStream& os, + const size_t start, + const size_t length +); /** Copy data from one stream into another stream using a buffered method * and notify progress state of the operation. @@ -66,9 +68,12 @@ VMIME_EXPORT size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, * @param progress listener to notify * @return number of bytes copied */ - -VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os, - const size_t length, progressListener* progress); +VMIME_EXPORT size_t bufferedStreamCopy( + inputStream& is, + outputStream& os, + const size_t length, + progressListener* progress +); } // utility @@ -76,4 +81,3 @@ VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os, #endif // VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED - diff --git a/src/vmime/utility/stringProxy.cpp b/src/vmime/utility/stringProxy.cpp index 67c96816..57d44069 100644 --- a/src/vmime/utility/stringProxy.cpp +++ b/src/vmime/utility/stringProxy.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,116 +34,128 @@ namespace utility { stringProxy::stringProxy() - : m_start(0), m_end(0) -{ + : m_start(0), + m_end(0) { + } stringProxy::stringProxy(const stringProxy& s) - : m_buffer(s.m_buffer), m_start(s.m_start), m_end(s.m_end) -{ + : m_buffer(s.m_buffer), + m_start(s.m_start), + m_end(s.m_end) { + } stringProxy::stringProxy(const string& s, const size_t start, const size_t end) - : m_buffer(s), m_start(start), - m_end(end == std::numeric_limits ::max() ? s.length() : end) -{ + : m_buffer(s), + m_start(start), + m_end(end == std::numeric_limits ::max() ? s.length() : end) { + } -void stringProxy::set(const string& s, const size_t start, const size_t end) -{ +void stringProxy::set(const string& s, const size_t start, const size_t end) { + m_buffer = s; m_start = start; - if (end == std::numeric_limits ::max()) + if (end == std::numeric_limits ::max()) { m_end = s.length(); - else + } else { m_end = end; + } } -void stringProxy::detach() -{ +void stringProxy::detach() { + m_buffer.clear(); m_start = m_end = 0; } -stringProxy& stringProxy::operator=(const stringProxy& s) -{ +stringProxy& stringProxy::operator=(const stringProxy& s) { + m_buffer = s.m_buffer; m_start = s.m_start; m_end = s.m_end; - return (*this); + return *this; } -stringProxy& stringProxy::operator=(const string& s) -{ +stringProxy& stringProxy::operator=(const string& s) { + m_buffer = s; m_start = 0; m_end = s.length(); - return (*this); + return *this; } -void stringProxy::extract(outputStream& os, const size_t start, const size_t end, - utility::progressListener* progress) const -{ +void stringProxy::extract( + outputStream& os, + const size_t start, + const size_t end, + utility::progressListener* progress +) const { + size_t len = 0; - if (end == std::numeric_limits ::max()) + if (end == std::numeric_limits ::max()) { len = m_end - start - m_start; - else if (end > start) + } else if (end > start) { len = end - start; + } - if (progress) + if (progress) { progress->start(len); + } os.write(m_buffer.data() + m_start + start, len); - if (progress) - { + if (progress) { progress->progress(len, len); progress->stop(len); } } -size_t stringProxy::length() const -{ - return (m_end - m_start); +size_t stringProxy::length() const { + + return m_end - m_start; } -size_t stringProxy::start() const -{ - return (m_start); +size_t stringProxy::start() const { + + return m_start; } -size_t stringProxy::end() const -{ - return (m_end); +size_t stringProxy::end() const { + + return m_end; } -std::ostream& operator<<(std::ostream& os, const stringProxy& s) -{ +std::ostream& operator<<(std::ostream& os, const stringProxy& s) { + outputStreamAdapter adapter(os); s.extract(adapter); - return (os); + + return os; } -outputStream& operator<<(outputStream& os, const stringProxy& s) -{ +outputStream& operator<<(outputStream& os, const stringProxy& s) { + s.extract(os); - return (os); + + return os; } diff --git a/src/vmime/utility/stringProxy.hpp b/src/vmime/utility/stringProxy.hpp index e5efa135..ac883c02 100644 --- a/src/vmime/utility/stringProxy.hpp +++ b/src/vmime/utility/stringProxy.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,9 +41,8 @@ namespace utility { * advantage of the COW (copy-on-write) system that might * be used in "std::string" implementation. */ +class VMIME_EXPORT stringProxy { -class VMIME_EXPORT stringProxy -{ public: // Consruction @@ -60,7 +59,12 @@ public: // Extract some portion (or whole) of the string // and output it into a stream. - void extract(outputStream& os, const size_t start = 0, const size_t end = std::numeric_limits ::max(), utility::progressListener* progress = NULL) const; + void extract( + outputStream& os, + const size_t start = 0, + const size_t end = std::numeric_limits ::max(), + utility::progressListener* progress = NULL + ) const; // Return the "virtual" length of the string size_t length() const; diff --git a/src/vmime/utility/stringUtils.cpp b/src/vmime/utility/stringUtils.cpp index 9567eac6..5f3c727a 100644 --- a/src/vmime/utility/stringUtils.cpp +++ b/src/vmime/utility/stringUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,30 +29,32 @@ namespace vmime { namespace utility { -bool stringUtils::isStringEqualNoCase - (const string& s1, const char* s2, const size_t n) -{ +bool stringUtils::isStringEqualNoCase(const string& s1, const char* s2, const size_t n) { + // 'n' is the number of characters to compare // 's2' must be in lowercase letters only - if (s1.length() < n) + if (s1.length() < n) { return (false); + } const std::ctype & fac = std::use_facet >(std::locale::classic()); bool equal = true; - for (size_t i = 0 ; equal && i < n ; ++i) + for (size_t i = 0 ; equal && i < n ; ++i) { equal = (fac.tolower(static_cast (s1[i])) == s2[i]); + } - return (equal); + return equal; } -bool stringUtils::isStringEqualNoCase(const string& s1, const string& s2) -{ - if (s1.length() != s2.length()) - return (false); +bool stringUtils::isStringEqualNoCase(const string& s1, const string& s2) { + + if (s1.length() != s2.length()) { + return false; + } const std::ctype & fac = std::use_facet >(std::locale::classic()); @@ -60,19 +62,24 @@ bool stringUtils::isStringEqualNoCase(const string& s1, const string& s2) bool equal = true; const string::const_iterator end = s1.end(); - for (string::const_iterator i = s1.begin(), j = s2.begin(); i != end ; ++i, ++j) + for (string::const_iterator i = s1.begin(), j = s2.begin(); i != end ; ++i, ++j) { equal = (fac.tolower(static_cast (*i)) == fac.tolower(static_cast (*j))); + } - return (equal); + return equal; } -bool stringUtils::isStringEqualNoCase - (const string::const_iterator begin, const string::const_iterator end, - const char* s, const size_t n) -{ - if (static_cast (end - begin) < n) - return (false); +bool stringUtils::isStringEqualNoCase( + const string::const_iterator begin, + const string::const_iterator end, + const char* s, + const size_t n +) { + + if (static_cast (end - begin) < n) { + return false; + } const std::ctype & fac = std::use_facet >(std::locale::classic()); @@ -81,91 +88,98 @@ bool stringUtils::isStringEqualNoCase char* c = const_cast(s); size_t r = n; - for (string::const_iterator i = begin ; equal && r && *c ; ++i, ++c, --r) + for (string::const_iterator i = begin ; equal && r && *c ; ++i, ++c, --r) { equal = (fac.tolower(static_cast (*i)) == static_cast (*c)); + } - return (r == 0 && equal); + return r == 0 && equal; } -const string stringUtils::toLower(const string& str) -{ +const string stringUtils::toLower(const string& str) { + const std::ctype & fac = std::use_facet >(std::locale::classic()); string out; out.resize(str.size()); - for (size_t i = 0, len = str.length() ; i < len ; ++i) + for (size_t i = 0, len = str.length() ; i < len ; ++i) { out[i] = fac.tolower(static_cast (str[i])); + } return out; } -const string stringUtils::toUpper(const string& str) -{ +const string stringUtils::toUpper(const string& str) { + const std::ctype & fac = std::use_facet >(std::locale::classic()); string out; out.resize(str.size()); - for (size_t i = 0, len = str.length() ; i < len ; ++i) + for (size_t i = 0, len = str.length() ; i < len ; ++i) { out[i] = fac.toupper(static_cast (str[i])); + } return out; } -const string stringUtils::trim(const string& str) -{ +const string stringUtils::trim(const string& str) { + string::const_iterator b = str.begin(); string::const_iterator e = str.end(); - if (b != e) - { + if (b != e) { + for ( ; b != e && parserHelpers::isSpace(*b) ; ++b) {} for ( ; e != b && parserHelpers::isSpace(*(e - 1)) ; --e) {} } - return (string(b, e)); + return string(b, e); } -size_t stringUtils::countASCIIchars - (const string::const_iterator begin, const string::const_iterator end) -{ +size_t stringUtils::countASCIIchars( + const string::const_iterator begin, + const string::const_iterator end +) { + size_t count = 0; - for (string::const_iterator i = begin ; i != end ; ++i) - { - if (parserHelpers::isAscii(*i)) - { - if (*i != '=' || ((i + 1) != end && *(i + 1) != '?')) // To avoid bad behaviour... + for (string::const_iterator i = begin ; i != end ; ++i) { + + if (parserHelpers::isAscii(*i)) { + + if (*i != '=' || ((i + 1) != end && *(i + 1) != '?')) { // To avoid bad behaviour... ++count; + } } } - return (count); + return count; } -bool stringUtils::is7bit(const string& str) -{ +bool stringUtils::is7bit(const string& str) { + return countASCIIchars(str.begin(), str.end()) == str.length(); } -size_t stringUtils::findFirstNonASCIIchar - (const string::const_iterator begin, const string::const_iterator end) -{ +size_t stringUtils::findFirstNonASCIIchar( + const string::const_iterator begin, + const string::const_iterator end +) { + size_t pos = string::npos; - for (string::const_iterator i = begin ; i != end ; ++i) - { - if (!parserHelpers::isAscii(*i)) - { + for (string::const_iterator i = begin ; i != end ; ++i) { + + if (!parserHelpers::isAscii(*i)) { pos = i - begin; break; } @@ -175,34 +189,36 @@ size_t stringUtils::findFirstNonASCIIchar } -const string stringUtils::unquote(const string& str) -{ - if (str.length() < 2) - return str; +const string stringUtils::unquote(const string& str) { - if (str[0] != '"' || str[str.length() - 1] != '"') + if (str.length() < 2) { return str; + } + + if (str[0] != '"' || str[str.length() - 1] != '"') { + return str; + } string res; res.reserve(str.length()); bool escaped = false; - for (string::const_iterator it = str.begin() + 1, end = str.end() - 1 ; it != end ; ++it) - { + for (string::const_iterator it = str.begin() + 1, end = str.end() - 1 ; it != end ; ++it) { + const char c = *it; - if (escaped) - { + if (escaped) { + res += c; escaped = false; - } - else if (!escaped && c == '\\') - { + + } else if (!escaped && c == '\\') { + escaped = true; - } - else - { + + } else { + res += c; } } @@ -211,20 +227,23 @@ const string stringUtils::unquote(const string& str) } -bool stringUtils::needQuoting(const string& str, const string& specialChars) -{ +bool stringUtils::needQuoting(const string& str, const string& specialChars) { + return str.find_first_of(specialChars.c_str()) != string::npos; } -string stringUtils::quote - (const string& str, const string& escapeSpecialChars, const string& escapeChar) -{ +string stringUtils::quote( + const string& str, + const string& escapeSpecialChars, + const string& escapeChar +) { + std::ostringstream oss; size_t lastPos = 0, pos = 0; - while ((pos = str.find_first_of(escapeSpecialChars, lastPos)) != string::npos) - { + while ((pos = str.find_first_of(escapeSpecialChars, lastPos)) != string::npos) { + oss << str.substr(lastPos, pos - lastPos) << escapeChar << str[pos]; @@ -238,22 +257,22 @@ string stringUtils::quote } -bool stringUtils::isValidHostname(const vmime::string& hostname) -{ +bool stringUtils::isValidHostname(const vmime::string& hostname) { + short numberOfDots = 0; return isValidFQDNImpl(hostname, &numberOfDots); } -bool stringUtils::isValidFQDN(const vmime::string& fqdn) -{ +bool stringUtils::isValidFQDN(const vmime::string& fqdn) { + short numberOfDots = 0; return isValidFQDNImpl(fqdn, &numberOfDots) && numberOfDots >= 2; } -bool stringUtils::isValidFQDNImpl(const vmime::string& fqdn, short* numberOfDots) -{ +bool stringUtils::isValidFQDNImpl(const vmime::string& fqdn, short* numberOfDots) { + bool alphanumOnly = true; bool invalid = false; bool previousIsDot = true; // dot is not allowed as the first char @@ -261,8 +280,8 @@ bool stringUtils::isValidFQDNImpl(const vmime::string& fqdn, short* numberOfDots *numberOfDots = 0; - for (size_t i = 0, n = fqdn.length() ; alphanumOnly && !invalid && i < n ; ++i) - { + for (size_t i = 0, n = fqdn.length() ; alphanumOnly && !invalid && i < n ; ++i) { + const char c = fqdn[i]; alphanumOnly = ( @@ -273,36 +292,35 @@ bool stringUtils::isValidFQDNImpl(const vmime::string& fqdn, short* numberOfDots || (c == '-') ); - if (c == '-') - { - if (previousIsDot) - { + if (c == '-') { + + if (previousIsDot) { invalid = true; // dash is not allowed as the first char } previousIsDot = false; previousIsDash = true; - } - else if (c == '.') - { - if (previousIsDash) - { + + } else if (c == '.') { + + if (previousIsDash) { + invalid = true; // dash is not allowed as the first char - } - else if (previousIsDot) - { + + } else if (previousIsDot) { + invalid = true; // consecutive dots are not allowed - } - else - { + + } else { + ++*numberOfDots; previousIsDot = true; } previousIsDash = false; - } - else - { + + } else { + previousIsDot = false; previousIsDash = false; } diff --git a/src/vmime/utility/stringUtils.hpp b/src/vmime/utility/stringUtils.hpp index 012b08e5..46789406 100644 --- a/src/vmime/utility/stringUtils.hpp +++ b/src/vmime/utility/stringUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,9 +37,8 @@ namespace utility { /** Miscellaneous functions related to strings. */ +class VMIME_EXPORT stringUtils { -class VMIME_EXPORT stringUtils -{ public: /** Makes a string from bytes. @@ -48,8 +47,8 @@ public: * @param count number of bytes to use from buffer * @return a string object containing a copy of the specified data */ - static const string makeStringFromBytes(const byte_t* data, const size_t count) - { + static const string makeStringFromBytes(const byte_t* data, const size_t count) { + return string(reinterpret_cast (data), count); } @@ -58,8 +57,8 @@ public: * @param str string * @return pointer to the first byte of the string */ - static const byte_t* bytesFromString(const string& str) - { + static const byte_t* bytesFromString(const string& str) { + return reinterpret_cast (str.data()); } @@ -68,8 +67,8 @@ public: * @param str string * @return pointer to the first byte of the string */ - static const byte_t* bytesFromString(const char* str) - { + static const byte_t* bytesFromString(const char* str) { + return reinterpret_cast (str); } @@ -80,8 +79,8 @@ public: * @param count number of bytes to use from buffer * @return a reference to modified string */ - static string& appendBytesToString(string& str, const byte_t* data, const size_t count) - { + static string& appendBytesToString(string& str, const byte_t* data, const size_t count) { + str.append(reinterpret_cast (data), count); return str; } @@ -114,7 +113,12 @@ public: * @param n length of the second string * @return true if the two strings compare equally, false otherwise */ - static bool isStringEqualNoCase(const string::const_iterator begin, const string::const_iterator end, const char* s, const size_t n); + static bool isStringEqualNoCase( + const string::const_iterator begin, + const string::const_iterator end, + const char* s, + const size_t n + ); /** Transform all the characters in a string to lower-case. * \warning Use this with ASCII-only strings. @@ -146,7 +150,10 @@ public: * @param end end position * @return number of ASCII characters */ - static size_t countASCIIchars(const string::const_iterator begin, const string::const_iterator end); + static size_t countASCIIchars( + const string::const_iterator begin, + const string::const_iterator end + ); /** Returns whether the specified string is composed exclusively * of 7-bit ASCII characters. @@ -162,7 +169,10 @@ public: * @param end end position * @return position since begin, or string::npos */ - static size_t findFirstNonASCIIchar(const string::const_iterator begin, const string::const_iterator end); + static size_t findFirstNonASCIIchar( + const string::const_iterator begin, + const string::const_iterator end + ); /** Convert the specified value to a string value. * @@ -170,14 +180,14 @@ public: * @return value converted from type 'TYPE' */ template - static const string toString(const TYPE& value) - { + static const string toString(const TYPE& value) { + std::ostringstream oss; oss.imbue(std::locale::classic()); oss << value; - return (oss.str()); + return oss.str(); } /** Convert the specified string value to a value of @@ -187,8 +197,8 @@ public: * @return value converted into type 'TYPE' */ template - static const TYPE fromString(const string& value) - { + static const TYPE fromString(const string& value) { + TYPE ret; std::istringstream iss(value); @@ -196,7 +206,7 @@ public: iss >> ret; - return (ret); + return ret; } /** Unquote the specified string and transform escaped characters. @@ -213,8 +223,10 @@ public: * string to be quoted * @return true if the string needs to be quoted, false otherwise */ - static bool needQuoting(const string& str, - const string& specialChars = " \t\"(),:;<>@[\\]"); + static bool needQuoting( + const string& str, + const string& specialChars = " \t\"(),:;<>@[\\]" + ); /** Quotes the specified string. * @@ -223,7 +235,11 @@ public: * @param escapeChar character that will be used for escaping (eg. '\') * @return quoted string */ - static string quote(const string& str, const string& escapeSpecialChars, const string& escapeChar); + static string quote( + const string& str, + const string& escapeSpecialChars, + const string& escapeChar + ); /** Return whether the specified string is a valid host name * or domain name. diff --git a/src/vmime/utility/sync/autoLock.hpp b/src/vmime/utility/sync/autoLock.hpp index a0ac90f6..a3d3a7cb 100644 --- a/src/vmime/utility/sync/autoLock.hpp +++ b/src/vmime/utility/sync/autoLock.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,20 +35,19 @@ namespace sync { /** Critical section wrapper class */ - template -class VMIME_EXPORT autoLock : public object -{ +class VMIME_EXPORT autoLock : public object { + public: autoLock(const shared_ptr & mutex) - : m_mutex(mutex) - { + : m_mutex(mutex) { + m_mutex->lock(); } - ~autoLock() - { + ~autoLock() { + m_mutex->unlock(); } diff --git a/src/vmime/utility/sync/criticalSection.cpp b/src/vmime/utility/sync/criticalSection.cpp index f2512d14..a1013cd9 100644 --- a/src/vmime/utility/sync/criticalSection.cpp +++ b/src/vmime/utility/sync/criticalSection.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,13 +29,13 @@ namespace utility { namespace sync { -criticalSection::criticalSection() -{ +criticalSection::criticalSection() { + } -criticalSection::~criticalSection() -{ +criticalSection::~criticalSection() { + } diff --git a/src/vmime/utility/sync/criticalSection.hpp b/src/vmime/utility/sync/criticalSection.hpp index 9703d73c..1e7008c6 100644 --- a/src/vmime/utility/sync/criticalSection.hpp +++ b/src/vmime/utility/sync/criticalSection.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace sync { /** Critical section class. */ +class VMIME_EXPORT criticalSection : public object { -class VMIME_EXPORT criticalSection : public object -{ public: virtual ~criticalSection(); diff --git a/src/vmime/utility/url.cpp b/src/vmime/utility/url.cpp index 4d7e2920..59cb1f51 100644 --- a/src/vmime/utility/url.cpp +++ b/src/vmime/utility/url.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,28 +44,38 @@ const string url::PROTOCOL_FTP = "ftp"; -url::url(const string& s) -{ +url::url(const string& s) { + parse(s); } -url::url(const url& u) -{ +url::url(const url& u) { + operator=(u); } -url::url(const string& protocol, const string& host, const port_t port, - const string& path, const string& username, const string& password) - : m_protocol(protocol), m_username(username), m_password(password), - m_host(host), m_port(port), m_path(path) -{ +url::url( + const string& protocol, + const string& host, + const port_t port, + const string& path, + const string& username, + const string& password +) + : m_protocol(protocol), + m_username(username), + m_password(password), + m_host(host), + m_port(port), + m_path(path) { + } -url& url::operator=(const url& u) -{ +url& url::operator=(const url& u) { + m_protocol = u.m_protocol; m_username = u.m_username; @@ -78,37 +88,37 @@ url& url::operator=(const url& u) m_params = u.m_params; - return (*this); + return *this; } -url& url::operator=(const string& s) -{ +url& url::operator=(const string& s) { + parse(s); - return (*this); + return *this; } -url::operator string() const -{ +url::operator string() const { + return build(); } -const string url::build() const -{ +const string url::build() const { + std::ostringstream oss; oss.imbue(std::locale::classic()); oss << m_protocol << "://"; - if (!m_username.empty()) - { + if (!m_username.empty()) { + oss << urlUtils::encode(m_username); - if (!m_password.empty()) - { + if (!m_password.empty()) { + oss << ":"; oss << urlUtils::encode(m_password); } @@ -118,31 +128,33 @@ const string url::build() const oss << urlUtils::encode(m_host); - if (m_port != UNSPECIFIED_PORT) - { + if (m_port != UNSPECIFIED_PORT) { + oss << ":"; oss << m_port; } - if (!m_path.empty()) - { + if (!m_path.empty()) { + oss << "/"; oss << urlUtils::encode(m_path); } - if (!m_params.empty()) - { - if (m_path.empty()) + if (!m_params.empty()) { + + if (m_path.empty()) { oss << "/"; + } oss << "?"; for (std::map ::const_iterator it = m_params.begin() ; - it != m_params.end() ; ++it) - { - if (it != m_params.begin()) + it != m_params.end() ; ++it) { + + if (it != m_params.begin()) { oss << "&"; + } oss << urlUtils::encode((*it).first); oss << "="; @@ -150,22 +162,28 @@ const string url::build() const } } - return (oss.str()); + return oss.str(); } -void url::parse(const string& str) -{ +void url::parse(const string& str) { + // Protocol const size_t protoEnd = str.find("://"); - if (protoEnd == string::npos) throw exceptions::malformed_url("No protocol separator"); + + if (protoEnd == string::npos) { + throw exceptions::malformed_url("No protocol separator"); + } const string proto = utility::stringUtils::toLower(string(str.begin(), str.begin() + protoEnd)); // Username/password size_t slashPos = str.find('/', protoEnd + 3); - if (slashPos == string::npos) slashPos = str.length(); + + if (slashPos == string::npos) { + slashPos = str.length(); + } size_t atPos = str.rfind('@', slashPos); string hostPart; @@ -173,32 +191,32 @@ void url::parse(const string& str) string username; string password; - if (proto == PROTOCOL_FILE) - { + if (proto == PROTOCOL_FILE) { + // No user name, password and host part. slashPos = protoEnd + 3; - } - else - { - if (atPos != string::npos && atPos < slashPos) - { + + } else { + + if (atPos != string::npos && atPos < slashPos) { + const string userPart(str.begin() + protoEnd + 3, str.begin() + atPos); const size_t colonPos = userPart.find(':'); - if (colonPos == string::npos) - { + if (colonPos == string::npos) { + username = userPart; - } - else - { + + } else { + username = string(userPart.begin(), userPart.begin() + colonPos); password = string(userPart.begin() + colonPos + 1, userPart.end()); } hostPart = string(str.begin() + atPos + 1, str.begin() + slashPos); - } - else - { + + } else { + hostPart = string(str.begin() + protoEnd + 3, str.begin() + slashPos); } } @@ -209,12 +227,12 @@ void url::parse(const string& str) string host; string port; - if (colonPos == string::npos) - { + if (colonPos == string::npos) { + host = utility::stringUtils::trim(hostPart); - } - else - { + + } else { + host = utility::stringUtils::trim(string(hostPart.begin(), hostPart.begin() + colonPos)); port = utility::stringUtils::trim(string(hostPart.begin() + colonPos + 1, hostPart.end())); } @@ -225,35 +243,40 @@ void url::parse(const string& str) size_t paramSep = path.find_first_of('?'); - if (paramSep != string::npos) - { + if (paramSep != string::npos) { + params = string(path.begin() + paramSep + 1, path.end()); path.erase(path.begin() + paramSep, path.end()); } - if (path == "/") + if (path == "/") { path.clear(); + } // Some sanity check - if (proto.empty()) + if (proto.empty()) { + throw exceptions::malformed_url("No protocol specified"); - else if (host.empty()) - { + + } else if (host.empty()) { + // Accept empty host (eg. "file:///home/vincent/mydoc") - if (proto != PROTOCOL_FILE) + if (proto != PROTOCOL_FILE) { throw exceptions::malformed_url("No host specified"); + } } bool onlyDigit = true; for (string::const_iterator it = port.begin() ; - onlyDigit && it != port.end() ; ++it) - { + onlyDigit && it != port.end() ; ++it) { + onlyDigit = parserHelpers::isDigit(*it); } - if (!onlyDigit) + if (!onlyDigit) { throw exceptions::malformed_url("Port can only contain digits"); + } std::istringstream iss(port); iss.imbue(std::locale::classic()); @@ -261,36 +284,36 @@ void url::parse(const string& str) port_t portNum = 0; iss >> portNum; - if (portNum == 0) + if (portNum == 0) { portNum = UNSPECIFIED_PORT; + } // Extract parameters m_params.clear(); - if (!params.empty()) - { + if (!params.empty()) { + size_t pos = 0; - do - { + do { + const size_t start = pos; pos = params.find_first_of('&', pos); const size_t equal = params.find_first_of('=', start); - const size_t end = - (pos == string::npos ? params.length() : pos); + const size_t end = (pos == string::npos ? params.length() : pos); string name; string value; - if (equal == string::npos || equal > pos) // no value - { + if (equal == string::npos || equal > pos) { // no value + name = string(params.begin() + start, params.begin() + end); value = name; - } - else - { + + } else { + name = string(params.begin() + start, params.begin() + equal); value = string(params.begin() + equal + 1, params.begin() + end); } @@ -300,10 +323,11 @@ void url::parse(const string& str) m_params[name] = value; - if (pos != string::npos) + if (pos != string::npos) { ++pos; - } - while (pos != string::npos); + } + + } while (pos != string::npos); } // Now, save URL parts @@ -319,87 +343,87 @@ void url::parse(const string& str) } -const string& url::getProtocol() const -{ - return (m_protocol); +const string& url::getProtocol() const { + + return m_protocol; } -void url::setProtocol(const string& protocol) -{ +void url::setProtocol(const string& protocol) { + m_protocol = protocol; } -const string& url::getUsername() const -{ - return (m_username); +const string& url::getUsername() const { + + return m_username; } -void url::setUsername(const string& username) -{ +void url::setUsername(const string& username) { + m_username = username; } -const string& url::getPassword() const -{ - return (m_password); +const string& url::getPassword() const { + + return m_password; } -void url::setPassword(const string& password) -{ +void url::setPassword(const string& password) { + m_password = password; } -const string& url::getHost() const -{ - return (m_host); +const string& url::getHost() const { + + return m_host; } -void url::setHost(const string& host) -{ +void url::setHost(const string& host) { + m_host = host; } -port_t url::getPort() const -{ - return (m_port); +port_t url::getPort() const { + + return m_port; } -void url::setPort(const port_t port) -{ +void url::setPort(const port_t port) { + m_port = port; } -const string& url::getPath() const -{ - return (m_path); +const string& url::getPath() const { + + return m_path; } -void url::setPath(const string& path) -{ +void url::setPath(const string& path) { + m_path = path; } -const std::map & url::getParams() const -{ - return (m_params); +const std::map & url::getParams() const { + + return m_params; } -std::map & url::getParams() -{ - return (m_params); +std::map & url::getParams() { + + return m_params; } diff --git a/src/vmime/utility/url.hpp b/src/vmime/utility/url.hpp index 84aba618..8dfa3c45 100644 --- a/src/vmime/utility/url.hpp +++ b/src/vmime/utility/url.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,10 +36,12 @@ namespace utility { /** This class represents a Uniform Resource Locator (a pointer * to a "resource" on the World Wide Web). + * + * Format: + * "protocol://[username[:password]@]host[:port][/path]" */ +class VMIME_EXPORT url { -class VMIME_EXPORT url -{ public: /** Means "port not specified" (use default port). */ @@ -77,8 +79,14 @@ public: * @param username optional user name * @param password optional user password */ - url(const string& protocol, const string& host, const port_t port = UNSPECIFIED_PORT, - const string& path = "", const string& username = "", const string& password = ""); + url( + const string& protocol, + const string& host, + const port_t port = UNSPECIFIED_PORT, + const string& path = "", + const string& username = "", + const string& password = "" + ); /** Return the protocol of the URL (eg: "http"). @@ -182,8 +190,6 @@ private: const string build() const; void parse(const string& str); - // Format: - // "protocol://[username[:password]@]host[:port][/path]" string m_protocol; diff --git a/src/vmime/utility/urlUtils.cpp b/src/vmime/utility/urlUtils.cpp index 20818764..cf51a506 100644 --- a/src/vmime/utility/urlUtils.cpp +++ b/src/vmime/utility/urlUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -29,8 +29,8 @@ namespace vmime { namespace utility { -const string urlUtils::encode(const string& s) -{ +const string urlUtils::encode(const string& s) { + static const string RESERVED_CHARS = /* reserved */ "$&+,/:;=?@" /* unsafe */ "<>#%{}[]|\\^\"~`"; @@ -38,18 +38,18 @@ const string urlUtils::encode(const string& s) string result; result.reserve(s.length()); - for (string::const_iterator it = s.begin() ; it != s.end() ; ++it) - { + for (string::const_iterator it = s.begin() ; it != s.end() ; ++it) { + const char c = *it; if (parserHelpers::isPrint(c) && !parserHelpers::isSpace(c) && static_cast (c) <= 127 && - RESERVED_CHARS.find(c) == string::npos) - { + RESERVED_CHARS.find(c) == string::npos) { + result += c; - } - else - { + + } else { + char hex[4]; const unsigned char k = static_cast (c); @@ -62,70 +62,70 @@ const string urlUtils::encode(const string& s) } } - return (result); + return result; } -const string urlUtils::decode(const string& s) -{ +const string urlUtils::decode(const string& s) { + string result; result.reserve(s.length()); - for (string::const_iterator it = s.begin() ; it != s.end() ; ) - { + for (string::const_iterator it = s.begin() ; it != s.end() ; ) { + const char c = *it; - switch (c) - { - case '%': - { - ++it; // skip '%' + switch (c) { - const char_t p = (it != s.end() ? *(it++) : 0); - const char_t q = (it != s.end() ? *(it++) : 0); + case '%': { - unsigned int r = 0; + ++it; // skip '%' - switch (p) - { - case 0: r = '%'; break; - case 'a': case 'A': r = 10; break; - case 'b': case 'B': r = 11; break; - case 'c': case 'C': r = 12; break; - case 'd': case 'D': r = 13; break; - case 'e': case 'E': r = 14; break; - case 'f': case 'F': r = 15; break; - default: r = p - '0'; break; - } + const char_t p = (it != s.end() ? *(it++) : 0); + const char_t q = (it != s.end() ? *(it++) : 0); - if (q != 0) - { - r *= 16; + unsigned int r = 0; - switch (q) - { - case 'a': case 'A': r += 10; break; - case 'b': case 'B': r += 11; break; - case 'c': case 'C': r += 12; break; - case 'd': case 'D': r += 13; break; - case 'e': case 'E': r += 14; break; - case 'f': case 'F': r += 15; break; - default: r += q - '0'; break; + switch (p) { + + case 0: r = '%'; break; + case 'a': case 'A': r = 10; break; + case 'b': case 'B': r = 11; break; + case 'c': case 'C': r = 12; break; + case 'd': case 'D': r = 13; break; + case 'e': case 'E': r = 14; break; + case 'f': case 'F': r = 15; break; + default: r = p - '0'; break; } + + if (q != 0) { + + r *= 16; + + switch (q) { + + case 'a': case 'A': r += 10; break; + case 'b': case 'B': r += 11; break; + case 'c': case 'C': r += 12; break; + case 'd': case 'D': r += 13; break; + case 'e': case 'E': r += 14; break; + case 'f': case 'F': r += 15; break; + default: r += q - '0'; break; + } + } + + result += static_cast (r); + break; } + default: - result += static_cast (r); - break; - } - default: - - result += c; - ++it; - break; + result += c; + ++it; + break; } } - return (result); + return result; } diff --git a/src/vmime/utility/urlUtils.hpp b/src/vmime/utility/urlUtils.hpp index c21e7aa4..54ffa2ac 100644 --- a/src/vmime/utility/urlUtils.hpp +++ b/src/vmime/utility/urlUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,9 +35,8 @@ namespace utility { /** Miscellaneous functions related to URLs. */ +class VMIME_EXPORT urlUtils { -class VMIME_EXPORT urlUtils -{ public: /** Encode extended characters in a URL string (ASCII characters diff --git a/src/vmime/vmime.hpp b/src/vmime/vmime.hpp index 456daea3..16d64a2a 100644 --- a/src/vmime/vmime.hpp +++ b/src/vmime/vmime.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as diff --git a/src/vmime/word.cpp b/src/vmime/word.cpp index d2d53b2b..b8061eee 100644 --- a/src/vmime/word.cpp +++ b/src/vmime/word.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,45 +37,55 @@ #include "vmime/wordEncoder.hpp" -namespace vmime -{ +namespace vmime { word::word() - : m_charset(charset::getLocalCharset()) -{ + : m_charset(charset::getLocalCharset()) { + } word::word(const word& w) - : headerFieldValue(), m_buffer(w.m_buffer), - m_charset(w.m_charset), m_lang(w.m_lang) -{ + : headerFieldValue(), + m_buffer(w.m_buffer), + m_charset(w.m_charset), + m_lang(w.m_lang) { + } word::word(const string& buffer) // Defaults to local charset - : m_buffer(buffer), m_charset(charset::getLocalCharset()) -{ + : m_buffer(buffer), + m_charset(charset::getLocalCharset()) { + } word::word(const string& buffer, const charset& charset) - : m_buffer(buffer), m_charset(charset) -{ + : m_buffer(buffer), + m_charset(charset) { + } word::word(const string& buffer, const charset& charset, const string& lang) - : m_buffer(buffer), m_charset(charset), m_lang(lang) -{ + : m_buffer(buffer), + m_charset(charset), + m_lang(lang) { + } -shared_ptr word::parseNext - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition, parserState* state) -{ +shared_ptr word::parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state +) { + size_t pos = position; // Ignore white-spaces: @@ -85,10 +95,11 @@ shared_ptr word::parseNext // Always ignore newlines string whiteSpaces; - while (pos < end && parserHelpers::isSpace(buffer[pos])) - { - if (buffer[pos] != '\r' && buffer[pos] != '\n') // do not include newlines + while (pos < end && parserHelpers::isSpace(buffer[pos])) { + + if (buffer[pos] != '\r' && buffer[pos] != '\n') { // do not include newlines whiteSpaces += buffer[pos]; + } ++pos; } @@ -99,53 +110,56 @@ shared_ptr word::parseNext const charset defaultCharset = ctx.getInternationalizedEmailSupport() ? charset(charsets::UTF_8) : charset(charsets::US_ASCII); - while (pos < end) - { + while (pos < end) { + // End of line: does not occur in the middle of an encoded word. This is // used to remove folding white-spaces from unencoded text. - if (buffer[pos] == '\n') - { + if (buffer[pos] == '\n') { + size_t endPos = pos; - if (pos > position && buffer[pos - 1] == '\r') - { + if (pos > position && buffer[pos - 1] == '\r') { ++pos; --endPos; } - while (pos != end && parserHelpers::isSpace(buffer[pos])) + while (pos != end && parserHelpers::isSpace(buffer[pos])) { ++pos; + } unencoded += buffer.substr(startPos, endPos - startPos); - if (pos != end) // ignore white-spaces at end + if (pos != end) { // ignore white-spaces at end unencoded += ' '; + } startPos = pos; continue; - } + // Start of an encoded word - else if (pos + 8 < end && // 8 = "=?(.+)?(.+)?(.*)?=" - buffer[pos] == '=' && buffer[pos + 1] == '?') - { + } else if (pos + 8 < end && // 8 = "=?(.+)?(.+)?(.*)?=" + buffer[pos] == '=' && buffer[pos + 1] == '?') { + // Check whether there is some unencoded text before unencoded += buffer.substr(startPos, pos - startPos); - if (!unencoded.empty()) - { - if (state->prevIsEncoded && !state->isFirst) + if (!unencoded.empty()) { + + if (state->prevIsEncoded && !state->isFirst) { unencoded = whiteSpaces + unencoded; + } shared_ptr w = make_shared (unencoded, defaultCharset); w->setParsedBounds(position, pos); - if (newPosition) + if (newPosition) { *newPosition = pos; + } state->prevIsEncoded = false; state->isFirst = false; - return (w); + return w; } // ...else find the finish sequence '?=' and return an encoded word @@ -153,32 +167,33 @@ shared_ptr word::parseNext pos += 2; - while (pos < end && buffer[pos] != '?') + while (pos < end && buffer[pos] != '?') { ++pos; + } + + if (pos < end) { - if (pos < end) - { ++pos; // skip '?' between charset and encoding - while (pos < end && buffer[pos] != '?') + while (pos < end && buffer[pos] != '?') { ++pos; + } - if (pos < end) - { + if (pos < end) { ++pos; // skip '?' between encoding and encoded data } } - while (pos < end) - { - if (buffer[pos] == '\n') - { + while (pos < end) { + + if (buffer[pos] == '\n') { + // End of line not allowed in the middle of an encoded word: // treat this text as unencoded text (see *). break; - } - else if (buffer[pos] == '?' && pos + 1 < end && buffer[pos + 1] == '=') - { + + } else if (buffer[pos] == '?' && pos + 1 < end && buffer[pos + 1] == '=') { + // Found the finish sequence break; } @@ -186,59 +201,67 @@ shared_ptr word::parseNext ++pos; } - if (pos == end) // not a valid word (no finish sequence) + if (pos == end) { // not a valid word (no finish sequence) continue; - else if (buffer[pos] == '\n') // (*) + } else if (buffer[pos] == '\n') { // (*) continue; + } pos += 2; // ?= shared_ptr w = make_shared (); w->parseWithState(ctx, buffer, wordStart, pos, NULL, state); - if (newPosition) + if (newPosition) { *newPosition = pos; + } state->prevIsEncoded = true; state->isFirst = false; - return (w); + return w; } ++pos; } - if (startPos != end) - { - if (state->prevIsEncoded && !state->isFirst) + if (startPos != end) { + + if (state->prevIsEncoded && !state->isFirst) { unencoded = whiteSpaces + unencoded; + } unencoded += buffer.substr(startPos, end - startPos); } // Treat unencoded text at the end of the buffer - if (!unencoded.empty()) - { + if (!unencoded.empty()) { + shared_ptr w = make_shared (unencoded, defaultCharset); w->setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } state->prevIsEncoded = false; state->isFirst = false; - return (w); + return w; } - return (null); + return null; } -const std::vector > word::parseMultiple - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +const std::vector > word::parseMultiple( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + std::vector > res; shared_ptr w; @@ -246,31 +269,42 @@ const std::vector > word::parseMultiple parserState state; - while ((w = word::parseNext(ctx, buffer, pos, end, &pos, &state)) != NULL) + while ((w = word::parseNext(ctx, buffer, pos, end, &pos, &state))) { res.push_back(w); + } - if (newPosition) + if (newPosition) { *newPosition = pos; + } - return (res); + return res; } -void word::parseImpl - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition) -{ +void word::parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition +) { + parseWithState(ctx, buffer, position, end, newPosition, NULL); } -void word::parseWithState - (const parsingContext& ctx, const string& buffer, const size_t position, - const size_t end, size_t* newPosition, parserState* state) -{ +void word::parseWithState( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state +) { + if (position + 6 < end && // 6 = "=?(.+)?(.*)?=" - buffer[position] == '=' && buffer[position + 1] == '?') - { + buffer[position] == '=' && buffer[position + 1] == '?') { + string::const_iterator p = buffer.begin() + position + 2; const string::const_iterator pend = buffer.begin() + end; @@ -278,52 +312,52 @@ void word::parseWithState for ( ; p != pend && *p != '?' ; ++p) {} - if (p != pend) // a charset is specified - { + if (p != pend) { // a charset is specified + const string::const_iterator charsetEnd = p; const string::const_iterator encPos = ++p; // skip '?' for ( ; p != pend && *p != '?' ; ++p) {} - if (p != pend) // an encoding is specified - { + if (p != pend) { // an encoding is specified + //const string::const_iterator encEnd = p; const string::const_iterator dataPos = ++p; // skip '?' for ( ; p != pend && !(*p == '?' && *(p + 1) == '=') ; ++p) {} - if (p != pend) // some data is specified - { + if (p != pend) { // some data is specified + const string::const_iterator dataEnd = p; p += 2; // skip '?=' scoped_ptr theEncoder; // Base-64 encoding - if (*encPos == 'B' || *encPos == 'b') - { + if (*encPos == 'B' || *encPos == 'b') { + theEncoder.reset(new utility::encoder::b64Encoder()); - } + // Quoted-Printable encoding - else if (*encPos == 'Q' || *encPos == 'q') - { + } else if (*encPos == 'Q' || *encPos == 'q') { + theEncoder.reset(new utility::encoder::qpEncoder()); theEncoder->getProperties()["rfc2047"] = true; } - if (theEncoder) - { + if (theEncoder) { + // Extract charset and language const string charsetAndLang(charsetPos, charsetEnd); const string::size_type asteriskPos = charsetAndLang.find('*'); - if (asteriskPos != string::npos) - { + if (asteriskPos != string::npos) { + m_charset = charset(string(charsetAndLang.begin(), charsetAndLang.begin() + asteriskPos)); m_lang = string(charsetAndLang.begin() + asteriskPos + 1, charsetAndLang.end()); - } - else - { + + } else { + m_charset = charset(charsetAndLang); m_lang.clear(); } @@ -332,8 +366,8 @@ void word::parseWithState string encodedBuffer(dataPos, dataEnd); string decodedBuffer; - if (state && !state->undecodedBytes.empty()) - { + if (state && !state->undecodedBytes.empty()) { + encodedBuffer = state->undecodedBytes + encodedBuffer; state->undecodedBytes.clear(); } @@ -347,22 +381,24 @@ void word::parseWithState setParsedBounds(position, p - buffer.begin()); - if (newPosition) + if (newPosition) { *newPosition = (p - buffer.begin()); + } // For Base64 encoding, ensure all bytes have been decoded. // If there are remaining bytes, keep them for the next run. // // This allows decoding some insanities like: // =?utf-8?B?5Lit5?= =?utf-8?B?paH?= - if (*encPos == 'B' || *encPos == 'b') - { + if (*encPos == 'B' || *encPos == 'b') { + const size_t actualEncodedLen = encodedBuffer.length(); const size_t theoricalEncodedLen = ((decodedLen + ((decodedLen % 3) ? (3 - (decodedLen % 3)) : 0) ) / 3) * 4; - if (state && actualEncodedLen != theoricalEncodedLen) + if (state && actualEncodedLen != theoricalEncodedLen) { state->undecodedBytes.assign(dataPos + theoricalEncodedLen, dataEnd); + } } return; @@ -379,74 +415,86 @@ void word::parseWithState setParsedBounds(position, end); - if (newPosition) + if (newPosition) { *newPosition = end; + } } -void word::generateImpl(const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos) const -{ +void word::generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos +) const { + generate(ctx, os, curLinePos, newLinePos, 0, NULL); } -void word::generate(const generationContext& ctx, utility::outputStream& os, - const size_t curLinePos, size_t* newLinePos, const int flags, - generatorState* state) const -{ +void word::generate( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos, + const int flags, + generatorState* state +) const { + size_t curLineLength = curLinePos; generatorState defaultGeneratorState; - if (state == NULL) + if (!state) { state = &defaultGeneratorState; + } // Find out if encoding is forced or required by contents + charset bool encodingNeeded = false; - if ((flags & text::FORCE_NO_ENCODING) != 0) + if ((flags & text::FORCE_NO_ENCODING) != 0) { encodingNeeded = false; - else if ((flags & text::FORCE_ENCODING) != 0) + } else if ((flags & text::FORCE_ENCODING) != 0) { encodingNeeded = true; - else // auto-detect + } else { // auto-detect encodingNeeded = wordEncoder::isEncodingNeeded(ctx, m_buffer, m_charset, m_lang); + } // If text does not need to be encoded, quote the buffer (no folding is performed). if (!encodingNeeded && (flags & text::QUOTE_IF_NEEDED) && - utility::stringUtils::needQuoting(m_buffer)) - { + utility::stringUtils::needQuoting(m_buffer)) { + const string quoted = utility::stringUtils::quote(m_buffer, "\\\"", "\\"); os << '"' << quoted << '"'; curLineLength += 1 + quoted.length() + 1; - } + // If possible and requested (with flag), quote the buffer (no folding is performed). // Quoting is possible if and only if: // - the buffer does not need to be encoded // - the buffer does not contain quoting character (") // - there is enough remaining space on the current line to hold the whole buffer - else if (!encodingNeeded && - (flags & text::QUOTE_IF_POSSIBLE) && - m_buffer.find('"') == string::npos && - (curLineLength + 2 /* 2 x " */ + m_buffer.length()) < ctx.getMaxLineLength()) - { + } else if (!encodingNeeded && + (flags & text::QUOTE_IF_POSSIBLE) && + m_buffer.find('"') == string::npos && + (curLineLength + 2 /* 2 x " */ + m_buffer.length()) < ctx.getMaxLineLength()) { + os << '"' << m_buffer << '"'; curLineLength += 2 + m_buffer.length(); - } + // We will fold lines without encoding them. - else if (!encodingNeeded) - { + } else if (!encodingNeeded) { + string buffer; - if (ctx.getInternationalizedEmailSupport()) - { + if (ctx.getInternationalizedEmailSupport()) { + // Convert the buffer to UTF-8 charset::convert(m_buffer, buffer, m_charset, charsets::UTF_8); - } - else - { + + } else { + // Leave the buffer as-is buffer = m_buffer; } @@ -462,23 +510,23 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, size_t maxRunLength = 0; size_t curRunLength = 0; - for (string::const_iterator p = buffer.begin(), end = buffer.end() ; p != end ; ++p) - { - if (parserHelpers::isSpace(*p)) - { + for (string::const_iterator p = buffer.begin(), end = buffer.end() ; p != end ; ++p) { + + if (parserHelpers::isSpace(*p)) { + maxRunLength = std::max(maxRunLength, curRunLength); curRunLength = 0; - } - else - { + + } else { + curRunLength++; } } maxRunLength = std::max(maxRunLength, curRunLength); - if (((flags & text::FORCE_NO_ENCODING) == 0) && maxRunLength >= ctx.getMaxLineLength() - 3) - { + if (((flags & text::FORCE_NO_ENCODING) == 0) && maxRunLength >= ctx.getMaxLineLength() - 3) { + // Generate with encoding forced generate(ctx, os, curLinePos, newLinePos, flags | text::FORCE_ENCODING, state); return; @@ -494,46 +542,47 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, bool finished = false; bool newLine = false; - while (!finished) - { - for ( ; p != end ; ++p, ++curLineLength) - { + while (!finished) { + + for ( ; p != end ; ++p, ++curLineLength) { + // Exceeded maximum line length, but we have found a white-space // where we can cut the line... - if (curLineLength >= ctx.getMaxLineLength() && lastWSpos != end) + if (curLineLength >= ctx.getMaxLineLength() && lastWSpos != end) { break; + } - if (*p == ' ' || *p == '\t') - { + if (*p == ' ' || *p == '\t') { // Remember the position of this white-space character lastWSpos = p; } } - if (p != end) + if (p != end) { ++curLineLength; + } + + if (p == end || lastWSpos == end) { - if (p == end || lastWSpos == end) - { // If we are here, it means that we have found no whitespace // before the first "maxLineLength" characters. In this case, // we write the full line no matter of the max line length... if (!newLine && p != end && lastWSpos == end && - !state->isFirstWord && curLineStart == buffer.begin()) - { + !state->isFirstWord && curLineStart == buffer.begin()) { + // Here, we are continuing on the line of previous encoded // word, but there is not even enough space to put the // first word of this line, so we start a new line. - if (flags & text::NO_NEW_LINE_SEQUENCE) - { + if (flags & text::NO_NEW_LINE_SEQUENCE) { + os << CRLF; curLineLength = 0; state->lastCharIsSpace = true; - } - else - { + + } else { + os << NEW_LINE_SEQUENCE; curLineLength = NEW_LINE_SEQUENCE_LENGTH; @@ -543,32 +592,38 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, p = curLineStart; lastWSpos = end; newLine = true; - } - else - { - if (!state->isFirstWord && state->prevWordIsEncoded && !state->lastCharIsSpace && !parserHelpers::isSpace(*curLineStart)) + + } else { + + if (!state->isFirstWord && + state->prevWordIsEncoded && + !state->lastCharIsSpace && + !parserHelpers::isSpace(*curLineStart)) { + os << " "; // Separate from previous word + } os << string(curLineStart, p); - if (p != buffer.begin() && parserHelpers::isSpace(*(p - 1))) + if (p != buffer.begin() && parserHelpers::isSpace(*(p - 1))) { state->lastCharIsSpace = true; - else + } else { state->lastCharIsSpace = false; - - if (p == end) - { - finished = true; } - else - { - if (flags & text::NO_NEW_LINE_SEQUENCE) - { + + if (p == end) { + + finished = true; + + } else { + + if (flags & text::NO_NEW_LINE_SEQUENCE) { + os << CRLF; curLineLength = 0; - } - else - { + + } else { + os << NEW_LINE_SEQUENCE; curLineLength = NEW_LINE_SEQUENCE_LENGTH; } @@ -578,34 +633,37 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, newLine = true; } } - } - else - { + + } else { + // In this case, there will not be enough space on the line for all the // characters _after_ the last white-space; so we cut the line at this // last white-space. -#if 1 - if (curLineLength != NEW_LINE_SEQUENCE_LENGTH && !state->isFirstWord && state->prevWordIsEncoded) + if (curLineLength != NEW_LINE_SEQUENCE_LENGTH && + !state->isFirstWord && + state->prevWordIsEncoded) { + os << " "; // Separate from previous word -#endif + } os << string(curLineStart, lastWSpos); - if (lastWSpos > curLineStart && parserHelpers::isSpace(*(lastWSpos - 1))) + if (lastWSpos > curLineStart && parserHelpers::isSpace(*(lastWSpos - 1))) { state->lastCharIsSpace = true; - else + } else { state->lastCharIsSpace = false; + } + + if (flags & text::NO_NEW_LINE_SEQUENCE) { - if (flags & text::NO_NEW_LINE_SEQUENCE) - { os << CRLF; curLineLength = 0; state->lastCharIsSpace = true; - } - else - { + + } else { + os << NEW_LINE_SEQUENCE; curLineLength = NEW_LINE_SEQUENCE_LENGTH; @@ -619,7 +677,7 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, newLine = true; } } - } + /* RFC #2047: 4. Encodings @@ -632,8 +690,8 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, MUST be able to accept either encoding for any character set which it supports. */ - else - { + } else { + // We will encode _AND_ fold lines /* @@ -668,25 +726,25 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, // characters can be encoded, start a new line. bool startNewLine = true; - if (curLineLength + 2 < maxLineLength2) - { + if (curLineLength + 2 < maxLineLength2) { + const size_t remainingSpaceOnLine = maxLineLength2 - curLineLength - 2; - if (remainingSpaceOnLine < minWordLength + 10) - { + if (remainingSpaceOnLine < minWordLength + 10) { + // Space for no more than 10 encoded chars! // It is not worth while to continue on this line... startNewLine = true; - } - else - { + + } else { + // OK, there is enough usable space on the current line. startNewLine = false; } } - if (startNewLine) - { + if (startNewLine) { + os << NEW_LINE_SEQUENCE; curLineLength = NEW_LINE_SEQUENCE_LENGTH; @@ -694,16 +752,16 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, } // Encode and fold input buffer - if (!startNewLine && !state->isFirstWord && !state->lastCharIsSpace) - { + if (!startNewLine && !state->isFirstWord && !state->lastCharIsSpace) { + os << " "; // Separate from previous word ++curLineLength; state->lastCharIsSpace = true; } - for (unsigned int i = 0 ; ; ++i) - { + for (unsigned int i = 0 ; ; ++i) { + // Compute the number of encoded chars that will fit on this line const size_t fit = maxLineLength2 - minWordLength - (i == 0 ? curLineLength : NEW_LINE_SEQUENCE_LENGTH); @@ -711,12 +769,13 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, // Get the next encoded chunk const string chunk = wordEnc.getNextChunk(fit); - if (chunk.empty()) + if (chunk.empty()) { break; + } // Start a new encoded word - if (i != 0) - { + if (i != 0) { + os << NEW_LINE_SEQUENCE; curLineLength = NEW_LINE_SEQUENCE_LENGTH; } @@ -735,33 +794,36 @@ void word::generate(const generationContext& ctx, utility::outputStream& os, } } - if (newLinePos) + if (newLinePos) { *newLinePos = curLineLength; + } state->isFirstWord = false; } -word& word::operator=(const word& w) -{ +word& word::operator=(const word& w) { + m_buffer = w.m_buffer; m_charset = w.m_charset; m_lang = w.m_lang; - return (*this); + + return *this; } -word& word::operator=(const string& s) -{ +word& word::operator=(const string& s) { + m_buffer = s; m_charset = charset::getLocalCharset(); m_lang.clear(); - return (*this); + + return *this; } -void word::copyFrom(const component& other) -{ +void word::copyFrom(const component& other) { + const word& w = dynamic_cast (other); m_buffer = w.m_buffer; @@ -770,102 +832,106 @@ void word::copyFrom(const component& other) } -bool word::operator==(const word& w) const -{ - return (m_charset == w.m_charset && m_buffer == w.m_buffer && m_lang == w.m_lang); +bool word::operator==(const word& w) const { + + return m_charset == w.m_charset && m_buffer == w.m_buffer && m_lang == w.m_lang; } -bool word::operator!=(const word& w) const -{ - return (m_charset != w.m_charset || m_buffer != w.m_buffer || m_lang != w.m_lang); +bool word::operator!=(const word& w) const { + + return m_charset != w.m_charset || m_buffer != w.m_buffer || m_lang != w.m_lang; } -bool word::isEquivalent(const word& other) 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) +const string word::getConvertedText( + const charset& dest, + const charsetConverterOptions& opts +) const { + + if (dest == m_charset) { return m_buffer; // no conversion needed + } string out; - try - { + try { + charset::convert(m_buffer, out, m_charset, dest, opts); - } - catch (vmime::exceptions::charset_conv_error& e) - { + + } catch (vmime::exceptions::charset_conv_error& e) { + // Do not fail if charset is not recognized: // copy 'word' as raw text out = m_buffer; } - return (out); + return out; } -shared_ptr word::clone() const -{ +shared_ptr word::clone() const { + return make_shared (m_buffer, m_charset); } -const charset& word::getCharset() const -{ - return (m_charset); +const charset& word::getCharset() const { + + return m_charset; } -void word::setCharset(const charset& ch) -{ +void word::setCharset(const charset& ch) { + m_charset = ch; } -const string word::getLanguage() const -{ +const string word::getLanguage() const { + return m_lang; } -void word::setLanguage(const string& lang) -{ +void word::setLanguage(const string& lang) { + m_lang = lang; } -const string& word::getBuffer() const -{ - return (m_buffer); +const string& word::getBuffer() const { + + return m_buffer; } -string& word::getBuffer() -{ - return (m_buffer); +string& word::getBuffer() { + + return m_buffer; } -bool word::isEmpty() const -{ +bool word::isEmpty() const { + return m_buffer.empty(); } -void word::setBuffer(const string& buffer) -{ +void word::setBuffer(const string& buffer) { + m_buffer = buffer; } -const std::vector > word::getChildComponents() -{ +const std::vector > word::getChildComponents() { + return std::vector >(); } diff --git a/src/vmime/word.hpp b/src/vmime/word.hpp index e7d12715..1565a0be 100644 --- a/src/vmime/word.hpp +++ b/src/vmime/word.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -30,16 +30,14 @@ #include "vmime/charsetConverterOptions.hpp" -namespace vmime -{ +namespace vmime { /** A class that encapsulates an encoded-word (RFC-2047): * some text encoded into one specified charset. */ +class VMIME_EXPORT word : public headerFieldValue { -class VMIME_EXPORT word : public headerFieldValue -{ friend class text; public: @@ -145,8 +143,10 @@ public: * @param opts options for charset conversion * @return word converted to the specified charset */ - const string getConvertedText(const charset& dest, - const charsetConverterOptions& opts = charsetConverterOptions()) const; + const string getConvertedText( + const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions() + ) const; /** Replace data in this word by data in other word. * @@ -162,13 +162,15 @@ public: #ifndef VMIME_BUILDING_DOC - class generatorState - { + class generatorState { + public: generatorState() - : isFirstWord(true), prevWordIsEncoded(false), lastCharIsSpace(false) - { + : isFirstWord(true), + prevWordIsEncoded(false), + lastCharIsSpace(false) { + } bool isFirstWord; @@ -176,13 +178,14 @@ public: bool lastCharIsSpace; }; - class parserState - { + class parserState { + public: parserState() - : prevIsEncoded(false), isFirst(true) - { + : prevIsEncoded(false), + isFirst(true) { + } bool prevIsEncoded; @@ -194,59 +197,65 @@ public: protected: - void parseImpl - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition = NULL); + void parseImpl( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL + ); - void generateImpl - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos = 0, - size_t* newLinePos = NULL) const; + void generateImpl( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL + ) const; - void parseWithState - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition, - parserState* state); + void parseWithState( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state + ); public: using component::generate; #ifndef VMIME_BUILDING_DOC - void generate - (const generationContext& ctx, - utility::outputStream& os, - const size_t curLinePos, - size_t* newLinePos, - const int flags, - generatorState* state) const; + void generate( + const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos, + const int flags, + generatorState* state + ) const; #endif const std::vector > getChildComponents(); private: - static shared_ptr parseNext - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition, - parserState* state); + static shared_ptr parseNext( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + parserState* state + ); - static const std::vector > parseMultiple - (const parsingContext& ctx, - const string& buffer, - const size_t position, - const size_t end, - size_t* newPosition); + static const std::vector > parseMultiple( + const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition + ); // The "m_buffer" of this word holds the data, and this data is encoded diff --git a/src/vmime/wordEncoder.cpp b/src/vmime/wordEncoder.cpp index b40f5371..4f47d047 100644 --- a/src/vmime/wordEncoder.cpp +++ b/src/vmime/wordEncoder.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,53 +37,64 @@ #include "vmime/utility/inputStreamStringAdapter.hpp" -namespace vmime -{ +namespace vmime { -wordEncoder::wordEncoder(const string& buffer, const charset& charset, const Encoding encoding) - : m_buffer(buffer), m_pos(0), m_length(buffer.length()), m_charset(charset), m_encoding(encoding) -{ - try - { +wordEncoder::wordEncoder( + const string& buffer, + const charset& charset, + const Encoding encoding +) + : m_buffer(buffer), + m_pos(0), + m_length(buffer.length()), + m_charset(charset), + m_encoding(encoding) { + + try { + string utf8Buffer; - vmime::charset::convert - (buffer, utf8Buffer, charset, vmime::charset(charsets::UTF_8)); + vmime::charset::convert( + buffer, utf8Buffer, charset, vmime::charset(charsets::UTF_8) + ); m_buffer = utf8Buffer; m_length = utf8Buffer.length(); m_simple = false; - } - catch (exceptions::charset_conv_error&) - { + + } catch (exceptions::charset_conv_error&) { + // Ignore exception. // We will fall back on simple encoding. m_simple = true; } - if (m_encoding == ENCODING_AUTO) + if (m_encoding == ENCODING_AUTO) { m_encoding = guessBestEncoding(buffer, charset); - - if (m_encoding == ENCODING_B64) - { - m_encoder = make_shared (); } - else // ENCODING_QP - { + + if (m_encoding == ENCODING_B64) { + + m_encoder = make_shared (); + + } else { // ENCODING_QP + m_encoder = make_shared (); m_encoder->getProperties()["rfc2047"] = true; } } -static size_t getUTF8CharLength - (const string& buffer, const size_t pos, const size_t length) -{ +static size_t getUTF8CharLength( + const string& buffer, + const size_t pos, + const size_t length +) { + // Gives the number of extra bytes in a UTF8 char, given the leading char - static const unsigned char UTF8_EXTRA_BYTES[256] = - { + static const unsigned char UTF8_EXTRA_BYTES[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -105,31 +116,33 @@ static size_t getUTF8CharLength const unsigned char c = buffer[pos]; const unsigned char n = UTF8_EXTRA_BYTES[c]; - if (n < length - pos) + if (n < length - pos) { return n + 1; - else + } else { return 1; + } } -const string wordEncoder::getNextChunk(const size_t maxLength) -{ +const string wordEncoder::getNextChunk(const size_t maxLength) { + const size_t remaining = m_length - m_pos; - if (remaining == 0) + if (remaining == 0) { return string(); + } vmime::string chunk; vmime::utility::outputStreamStringAdapter chunkStream(chunk); // Simple encoding - if (m_simple) - { + if (m_simple) { + // WARNING! Simple encoding can encode a non-integral number of // characters and then may generate incorrectly-formed words! - if (m_encoding == ENCODING_B64) - { + if (m_encoding == ENCODING_B64) { + // Here, we have a formula to compute the maximum number of source // bytes to encode knowing the maximum number of encoded chars. In // Base64 encoding, 3 bytes of input provide 4 bytes of output. @@ -141,17 +154,17 @@ const string wordEncoder::getNextChunk(const size_t maxLength) m_encoder->encode(in, chunkStream); m_pos += inputCount; - } - else // ENCODING_QP - { + + } else { // ENCODING_QP + // Compute exactly how much input bytes are needed to have an output // string length of less than 'maxLength' bytes. In Quoted-Printable // encoding, encoded bytes take 3 bytes. size_t inputCount = 0; size_t outputCount = 0; - while ((inputCount == 0 || outputCount < maxLength) && (inputCount < remaining)) - { + while ((inputCount == 0 || outputCount < maxLength) && (inputCount < remaining)) { + const unsigned char c = m_buffer[m_pos + inputCount]; inputCount++; @@ -164,24 +177,26 @@ const string wordEncoder::getNextChunk(const size_t maxLength) m_encoder->encode(in, chunkStream); m_pos += inputCount; } - } + // Fully RFC-compliant encoding - else - { + } else { + shared_ptr conv = charsetConverter::create(charsets::UTF_8, m_charset); size_t inputCount = 0; size_t outputCount = 0; string encodeBuffer; - while ((inputCount == 0 || outputCount < maxLength) && (inputCount < remaining)) - { + while ((inputCount == 0 || outputCount < maxLength) && (inputCount < remaining)) { + // Get the next UTF8 character const size_t inputCharLength = getUTF8CharLength(m_buffer, m_pos + inputCount, m_length); - const string inputChar(m_buffer.begin() + m_pos + inputCount, - m_buffer.begin() + m_pos + inputCount + inputCharLength); + const string inputChar( + m_buffer.begin() + m_pos + inputCount, + m_buffer.begin() + m_pos + inputCount + inputCharLength + ); // Convert back to original encoding string encodeBytes; @@ -190,15 +205,17 @@ const string wordEncoder::getNextChunk(const size_t maxLength) encodeBuffer += encodeBytes; // Compute number of output bytes - if (m_encoding == ENCODING_B64) - { - outputCount = std::max(static_cast (4), - (encodeBuffer.length() * 4) / 3); - } - else // ENCODING_QP - { - for (size_t i = 0, n = encodeBytes.length() ; i < n ; ++i) - { + if (m_encoding == ENCODING_B64) { + + outputCount = std::max( + static_cast (4), + (encodeBuffer.length() * 4) / 3 + ); + + } else { // ENCODING_QP + + for (size_t i = 0, n = encodeBytes.length() ; i < n ; ++i) { + const unsigned char c = encodeBytes[i]; outputCount += utility::encoder::qpEncoder::RFC2047_getEncodedLength(c); } @@ -218,60 +235,71 @@ const string wordEncoder::getNextChunk(const size_t maxLength) } -wordEncoder::Encoding wordEncoder::getEncoding() const -{ +wordEncoder::Encoding wordEncoder::getEncoding() const { + return m_encoding; } // static -bool wordEncoder::isEncodingNeeded - (const generationContext& ctx, const string& buffer, - const charset& charset, const string& lang) -{ - if (!ctx.getInternationalizedEmailSupport()) - { +bool wordEncoder::isEncodingNeeded( + const generationContext& ctx, + const string& buffer, + const charset& charset, + const string& lang +) { + + if (!ctx.getInternationalizedEmailSupport()) { + // Charset-specific encoding encoding recEncoding; - if (charset.getRecommendedEncoding(recEncoding)) + if (charset.getRecommendedEncoding(recEncoding)) { return true; + } // No encoding is needed if the buffer only contains ASCII chars - if (utility::stringUtils::findFirstNonASCIIchar(buffer.begin(), buffer.end()) != string::npos) + if (utility::stringUtils::findFirstNonASCIIchar(buffer.begin(), buffer.end()) != string::npos) { return true; + } } // Force encoding when there are only ASCII chars, but there is // also at least one of '\n' or '\r' (header fields) - if (buffer.find_first_of("\n\r") != string::npos) + if (buffer.find_first_of("\n\r") != string::npos) { return true; + } // If any RFC-2047 sequence is found in the buffer, encode it - if (buffer.find("=?") != string::npos || buffer.find("?=") != string::npos) + if (buffer.find("=?") != string::npos || buffer.find("?=") != string::npos) { return true; + } // If a language is specified, force encoding - if (!lang.empty()) + if (!lang.empty()) { return true; + } return false; } // static -wordEncoder::Encoding wordEncoder::guessBestEncoding - (const string& buffer, const charset& charset) -{ +wordEncoder::Encoding wordEncoder::guessBestEncoding( + const string& buffer, + const charset& charset +) { + // Charset-specific encoding encoding recEncoding; - if (charset.getRecommendedEncoding(recEncoding)) - { - if (recEncoding == encoding(encodingTypes::QUOTED_PRINTABLE)) + if (charset.getRecommendedEncoding(recEncoding)) { + + if (recEncoding == encoding(encodingTypes::QUOTED_PRINTABLE)) { return ENCODING_QP; - else + } else { return ENCODING_B64; + } } // Use Base64 if more than 40% non-ASCII, or Quoted-Printable else (default) @@ -279,14 +307,14 @@ wordEncoder::Encoding wordEncoder::guessBestEncoding utility::stringUtils::countASCIIchars(buffer.begin(), buffer.end()); const size_t asciiPercent = - (buffer.length() == 0 ? 100 : (100 * asciiCount) / buffer.length()); + buffer.length() == 0 ? 100 : (100 * asciiCount) / buffer.length(); - if (asciiPercent < 60) + if (asciiPercent < 60) { return ENCODING_B64; - else + } else { return ENCODING_QP; + } } } // vmime - diff --git a/src/vmime/wordEncoder.hpp b/src/vmime/wordEncoder.hpp index 8abd3d3c..e37bbe76 100644 --- a/src/vmime/wordEncoder.hpp +++ b/src/vmime/wordEncoder.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -28,8 +28,7 @@ #include "vmime/charset.hpp" -namespace vmime -{ +namespace vmime { namespace utility { @@ -41,23 +40,25 @@ class encoder; } // utility -/** Encodes words following RFC-2047. +/** Encodes words according to RFC-2047. */ +class VMIME_EXPORT wordEncoder { -class VMIME_EXPORT wordEncoder -{ public: /** Available encodings for RFC-2047. */ - enum Encoding - { + enum Encoding { ENCODING_AUTO, ENCODING_QP, ENCODING_B64 }; - wordEncoder(const string& buffer, const charset& charset, const Encoding encoding = ENCODING_AUTO); + wordEncoder( + const string& buffer, + const charset& charset, + const Encoding encoding = ENCODING_AUTO + ); /** Return the next chunk in the word. @@ -81,8 +82,12 @@ public: * @param lang language code, in the format specified by RFC-1766 * @return true if encoding is needed, false otherwise. */ - static bool isEncodingNeeded(const generationContext& ctx, const string& buffer, - const charset& charset, const string& lang); + static bool isEncodingNeeded( + const generationContext& ctx, + const string& buffer, + const charset& charset, + const string& lang + ); /** Guess the best RFC-2047 encoding to use for the specified buffer. * @@ -111,4 +116,3 @@ private: #endif // VMIME_WORDENCODER_HPP_INCLUDED - diff --git a/tests/misc/importanceHelperTest.cpp b/tests/misc/importanceHelperTest.cpp index 53c5c679..d04d730b 100644 --- a/tests/misc/importanceHelperTest.cpp +++ b/tests/misc/importanceHelperTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -47,8 +47,8 @@ VMIME_TEST_SUITE_BEGIN(importanceHelperTest) // resetImportance - void testResetImportance() - { + void testResetImportance() { + vmime::shared_ptr hdr = vmime::make_shared (); hdr->getField("Importance")->setValue("xxx"); @@ -66,9 +66,12 @@ VMIME_TEST_SUITE_BEGIN(importanceHelperTest) // setImportance - void testSetImportanceImpl(const vmime::misc::importanceHelper::Importance i, - const std::string& ImportanceValue, const std::string& XPriorityValue) - { + void testSetImportanceImpl( + const vmime::misc::importanceHelper::Importance i, + const std::string& ImportanceValue, + const std::string& XPriorityValue + ) { + vmime::shared_ptr hdr = vmime::make_shared (); vmime::misc::importanceHelper::setImportanceHeader(hdr, i); @@ -80,43 +83,56 @@ VMIME_TEST_SUITE_BEGIN(importanceHelperTest) VASSERT_EQ("4", XPriorityValue, hdr->findField("X-Priority")->getValue()->generate()); } - void testSetImportance1() - { - testSetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, - "high", "1 (Highest)"); + void testSetImportance1() { + + testSetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, + "high", "1 (Highest)" + ); } - void testSetImportance2() - { - testSetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_HIGH, - "high", "2 (High)"); + void testSetImportance2() { + + testSetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_HIGH, + "high", "2 (High)" + ); } - void testSetImportance3() - { - testSetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_NORMAL, - "normal", "3 (Normal)"); + void testSetImportance3() { + + testSetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_NORMAL, + "normal", "3 (Normal)" + ); } - void testSetImportance4() - { - testSetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_LOW, - "low", "4 (Low)"); + void testSetImportance4() { + + testSetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_LOW, + "low", "4 (Low)" + ); } - void testSetImportance5() - { - testSetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_LOWEST, - "low", "5 (Lowest)"); + void testSetImportance5() { + + testSetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_LOWEST, + "low", "5 (Lowest)" + ); } // getImportance - void testGetImportanceImpl(const vmime::misc::importanceHelper::Importance i1, + void testGetImportanceImpl( + const vmime::misc::importanceHelper::Importance i1, const vmime::misc::importanceHelper::Importance i2, - const std::string& ImportanceValue, const std::string& XPriorityValue) - { + const std::string& ImportanceValue, + const std::string& XPriorityValue + ) { + vmime::shared_ptr hdr1 = vmime::make_shared (); hdr1->getField("Importance")->setValue(ImportanceValue); @@ -128,35 +144,48 @@ VMIME_TEST_SUITE_BEGIN(importanceHelperTest) VASSERT_EQ("2", i2, vmime::misc::importanceHelper::getImportanceHeader(hdr2)); } - void testGetImportance1() - { - testGetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, - vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, "high", "1 (Highest)"); + void testGetImportance1() { + + testGetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, + vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, + "high", "1 (Highest)"); } - void testGetImportance2() - { - testGetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, - vmime::misc::importanceHelper::IMPORTANCE_HIGH, "high", "2 (High)"); + void testGetImportance2() { + + testGetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_HIGHEST, + vmime::misc::importanceHelper::IMPORTANCE_HIGH, + "high", "2 (High)" + ); } - void testGetImportance3() - { - testGetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_NORMAL, - vmime::misc::importanceHelper::IMPORTANCE_NORMAL, "normal", "3 (Normal)"); + void testGetImportance3() { + + testGetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_NORMAL, + vmime::misc::importanceHelper::IMPORTANCE_NORMAL, + "normal", "3 (Normal)" + ); } - void testGetImportance4() - { - testGetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_LOWEST, - vmime::misc::importanceHelper::IMPORTANCE_LOW, "low", "4 (Low)"); + void testGetImportance4() { + + testGetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_LOWEST, + vmime::misc::importanceHelper::IMPORTANCE_LOW, + "low", "4 (Low)" + ); } - void testGetImportance5() - { - testGetImportanceImpl(vmime::misc::importanceHelper::IMPORTANCE_LOWEST, - vmime::misc::importanceHelper::IMPORTANCE_LOWEST, "low", "5 (Lowest)"); + void testGetImportance5() { + + testGetImportanceImpl( + vmime::misc::importanceHelper::IMPORTANCE_LOWEST, + vmime::misc::importanceHelper::IMPORTANCE_LOWEST, + "low", "5 (Lowest)" + ); } VMIME_TEST_SUITE_END - diff --git a/tests/net/folderAttributesTest.cpp b/tests/net/folderAttributesTest.cpp index 06235399..da0e025d 100644 --- a/tests/net/folderAttributesTest.cpp +++ b/tests/net/folderAttributesTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VMIME_TEST_LIST_END - void testConstruct() - { + void testConstruct() { + vmime::net::folderAttributes attr; // Default values @@ -52,8 +52,8 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VASSERT_EQ("special-use", vmime::net::folderAttributes::SPECIALUSE_NONE, attr.getSpecialUse()); } - void testConstructCopy() - { + void testConstructCopy() { + std::vector userFlags; userFlags.push_back("\\XMyFlag1"); userFlags.push_back("\\XMyFlag2"); @@ -70,24 +70,24 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VASSERT("user-flags", attr2.getUserFlags() == attr.getUserFlags()); } - void testSetType() - { + void testSetType() { + vmime::net::folderAttributes attr; attr.setType(vmime::net::folderAttributes::TYPE_CONTAINS_FOLDERS); VASSERT_EQ("eq", vmime::net::folderAttributes::TYPE_CONTAINS_FOLDERS, attr.getType()); } - void testSetFlags() - { + void testSetFlags() { + vmime::net::folderAttributes attr; attr.setFlags(vmime::net::folderAttributes::FLAG_HAS_CHILDREN); VASSERT_EQ("eq", vmime::net::folderAttributes::FLAG_HAS_CHILDREN, attr.getFlags()); } - void testHasFlag() - { + void testHasFlag() { + vmime::net::folderAttributes attr; attr.setFlags(vmime::net::folderAttributes::FLAG_HAS_CHILDREN); @@ -95,8 +95,8 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VASSERT("has-not", !attr.hasFlag(vmime::net::folderAttributes::FLAG_NO_OPEN)); } - void testSetUserFlags() - { + void testSetUserFlags() { + std::vector userFlags; userFlags.push_back("\\XMyFlag1"); userFlags.push_back("\\XMyFlag2"); @@ -108,8 +108,8 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VASSERT("eq", attr.getUserFlags() == userFlags); } - void testHasUserFlag() - { + void testHasUserFlag() { + std::vector userFlags; userFlags.push_back("\\XMyFlag1"); userFlags.push_back("\\XMyFlag2"); @@ -123,8 +123,8 @@ VMIME_TEST_SUITE_BEGIN(folderAttributesTest) VASSERT("has-not", !attr.hasUserFlag("\\XMyFlag4")); } - void testSetSpecialUse() - { + void testSetSpecialUse() { + const int use = vmime::net::folderAttributes::SPECIALUSE_JUNK | vmime::net::folderAttributes::SPECIALUSE_TRASH; diff --git a/tests/net/imap/IMAPCommandTest.cpp b/tests/net/imap/IMAPCommandTest.cpp index f274bb27..cf3446d7 100644 --- a/tests/net/imap/IMAPCommandTest.cpp +++ b/tests/net/imap/IMAPCommandTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -60,24 +60,24 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VMIME_TEST_LIST_END - void testCreateCommand() - { + void testCreateCommand() { + vmime::shared_ptr cmd = IMAPCommand::createCommand("MY_COMMAND"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND", cmd->getText()); } - void testCreateCommandParams() - { + void testCreateCommandParams() { + vmime::shared_ptr cmd = IMAPCommand::createCommand("MY_COMMAND param1 param2"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND param1 param2", cmd->getText()); } - void testLOGIN() - { + void testLOGIN() { + vmime::shared_ptr cmd = IMAPCommand::LOGIN("username", "password"); VASSERT_NOT_NULL("Not null", cmd); @@ -85,24 +85,24 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Trace Text", "LOGIN {username} {password}", cmd->getTraceText()); } - void testAUTHENTICATE() - { + void testAUTHENTICATE() { + vmime::shared_ptr cmd = IMAPCommand::AUTHENTICATE("saslmechanism"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTHENTICATE saslmechanism", cmd->getText()); } - void testAUTHENTICATE_InitialResponse() - { + void testAUTHENTICATE_InitialResponse() { + vmime::shared_ptr cmd = IMAPCommand::AUTHENTICATE("saslmechanism", "initial-response"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTHENTICATE saslmechanism initial-response", cmd->getText()); } - void testLIST() - { + void testLIST() { + vmime::shared_ptr cmd = IMAPCommand::LIST("ref-name", "mailbox-name"); VASSERT_NOT_NULL("Not null", cmd); @@ -114,47 +114,52 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "LIST \"ref name\" mailbox-name", cmdQuote->getText()); } - void testSELECT() - { + void testSELECT() { + std::vector params; params.push_back("param-1"); params.push_back("param-2"); - vmime::shared_ptr cmdRO = IMAPCommand::SELECT - (/* readOnly */ true, "mailbox-name", std::vector ()); + vmime::shared_ptr cmdRO = IMAPCommand::SELECT( + /* readOnly */ true, "mailbox-name", std::vector () + ); VASSERT_NOT_NULL("Not null", cmdRO); VASSERT_EQ("Text", "EXAMINE mailbox-name", cmdRO->getText()); - vmime::shared_ptr cmdROQuote = IMAPCommand::SELECT - (/* readOnly */ true, "mailbox name", std::vector ()); + vmime::shared_ptr cmdROQuote = IMAPCommand::SELECT( + /* readOnly */ true, "mailbox name", std::vector () + ); VASSERT_NOT_NULL("Not null", cmdROQuote); VASSERT_EQ("Text", "EXAMINE \"mailbox name\"", cmdROQuote->getText()); - vmime::shared_ptr cmdRW = IMAPCommand::SELECT - (/* readOnly */ false, "mailbox-name", std::vector ()); + vmime::shared_ptr cmdRW = IMAPCommand::SELECT( + /* readOnly */ false, "mailbox-name", std::vector () + ); VASSERT_NOT_NULL("Not null", cmdRW); VASSERT_EQ("Text", "SELECT mailbox-name", cmdRW->getText()); - vmime::shared_ptr cmdRWParams = IMAPCommand::SELECT - (/* readOnly */ false, "mailbox-name", params); + vmime::shared_ptr cmdRWParams = IMAPCommand::SELECT( + /* readOnly */ false, "mailbox-name", params + ); VASSERT_NOT_NULL("Not null", cmdRWParams); VASSERT_EQ("Text", "SELECT mailbox-name (param-1 param-2)", cmdRWParams->getText()); - vmime::shared_ptr cmdRWQuote = IMAPCommand::SELECT - (/* readOnly */ false, "mailbox name", std::vector ()); + vmime::shared_ptr cmdRWQuote = IMAPCommand::SELECT( + /* readOnly */ false, "mailbox name", std::vector () + ); VASSERT_NOT_NULL("Not null", cmdRWQuote); VASSERT_EQ("Text", "SELECT \"mailbox name\"", cmdRWQuote->getText()); } - void testSTATUS() - { + void testSTATUS() { + std::vector attribs; attribs.push_back("attrib-1"); attribs.push_back("attrib-2"); @@ -174,8 +179,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "STATUS \"mailbox name\" (attrib-1 attrib-2)", cmdQuote->getText()); } - void testCREATE() - { + void testCREATE() { + std::vector params; params.push_back("param-1"); params.push_back("param-2"); @@ -202,8 +207,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "CREATE mailbox-name", cmdNoParam->getText()); } - void testDELETE() - { + void testDELETE() { + vmime::shared_ptr cmd = IMAPCommand::DELETE("mailbox-name"); @@ -218,8 +223,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "DELETE \"mailbox name\"", cmdQuote->getText()); } - void testRENAME() - { + void testRENAME() { + vmime::shared_ptr cmd = IMAPCommand::RENAME("mailbox-name", "new-mailbox-name"); @@ -234,8 +239,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "RENAME \"mailbox name\" \"new mailbox name\"", cmdQuote->getText()); } - void testFETCH() - { + void testFETCH() { + std::vector params; params.push_back("param-1"); params.push_back("param-2"); @@ -269,57 +274,63 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "UID FETCH 42:47 (param-1 param-2)", cmdUIDs->getText()); } - void testSTORE() - { + void testSTORE() { + std::vector flags; flags.push_back("flag-1"); flags.push_back("flag-2"); - vmime::shared_ptr cmdNum = IMAPCommand::STORE - (vmime::net::messageSet::byNumber(42), vmime::net::message::FLAG_MODE_SET, flags); + vmime::shared_ptr cmdNum = IMAPCommand::STORE( + vmime::net::messageSet::byNumber(42), vmime::net::message::FLAG_MODE_SET, flags + ); VASSERT_NOT_NULL("Not null", cmdNum); VASSERT_EQ("Text", "STORE 42 FLAGS (flag-1 flag-2)", cmdNum->getText()); - vmime::shared_ptr cmdNums = IMAPCommand::STORE - (vmime::net::messageSet::byNumber(42, 47), vmime::net::message::FLAG_MODE_SET, flags); + vmime::shared_ptr cmdNums = IMAPCommand::STORE( + vmime::net::messageSet::byNumber(42, 47), vmime::net::message::FLAG_MODE_SET, flags + ); VASSERT_NOT_NULL("Not null", cmdNums); VASSERT_EQ("Text", "STORE 42:47 FLAGS (flag-1 flag-2)", cmdNums->getText()); - vmime::shared_ptr cmdUID = IMAPCommand::STORE - (vmime::net::messageSet::byUID(42), vmime::net::message::FLAG_MODE_SET, flags); + vmime::shared_ptr cmdUID = IMAPCommand::STORE( + vmime::net::messageSet::byUID(42), vmime::net::message::FLAG_MODE_SET, flags + ); VASSERT_NOT_NULL("Not null", cmdUID); VASSERT_EQ("Text", "UID STORE 42 FLAGS (flag-1 flag-2)", cmdUID->getText()); - vmime::shared_ptr cmdUIDs = IMAPCommand::STORE - (vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_SET, flags); + vmime::shared_ptr cmdUIDs = IMAPCommand::STORE( + vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_SET, flags + ); VASSERT_NOT_NULL("Not null", cmdUIDs); VASSERT_EQ("Text", "UID STORE 42:47 FLAGS (flag-1 flag-2)", cmdUIDs->getText()); - vmime::shared_ptr cmdAdd = IMAPCommand::STORE - (vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_ADD, flags); + vmime::shared_ptr cmdAdd = IMAPCommand::STORE( + vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_ADD, flags + ); VASSERT_NOT_NULL("Not null", cmdAdd); VASSERT_EQ("Text", "UID STORE 42:47 +FLAGS (flag-1 flag-2)", cmdAdd->getText()); - vmime::shared_ptr cmdRem = IMAPCommand::STORE - (vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_REMOVE, flags); + vmime::shared_ptr cmdRem = IMAPCommand::STORE( + vmime::net::messageSet::byUID(42, 47), vmime::net::message::FLAG_MODE_REMOVE, flags + ); VASSERT_NOT_NULL("Not null", cmdRem); VASSERT_EQ("Text", "UID STORE 42:47 -FLAGS (flag-1 flag-2)", cmdRem->getText()); } - void testAPPEND() - { + void testAPPEND() { + std::vector flags; flags.push_back("flag-1"); flags.push_back("flag-2"); @@ -347,8 +358,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "APPEND \"mailbox name\" (flag-1 flag-2) \"15-Mar-2014 23:11:47 +0200\" {1234}", cmdDate->getText()); } - void testCOPY() - { + void testCOPY() { + vmime::shared_ptr cmdNum = IMAPCommand::COPY(vmime::net::messageSet::byNumber(42), "mailbox-name"); @@ -384,8 +395,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "COPY 42:47 \"mailbox name\"", cmdQuote->getText()); } - void testSEARCH() - { + void testSEARCH() { + std::vector searchKeys; searchKeys.push_back("search-key-1"); searchKeys.push_back("search-key-2"); @@ -406,57 +417,58 @@ VMIME_TEST_SUITE_BEGIN(IMAPCommandTest) VASSERT_EQ("Text", "SEARCH CHARSET test-charset search-key-1 search-key-2", cmdCset->getText()); } - void testSTARTTLS() - { + void testSTARTTLS() { + vmime::shared_ptr cmd = IMAPCommand::STARTTLS(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "STARTTLS", cmd->getText()); } - void testCAPABILITY() - { + void testCAPABILITY() { + vmime::shared_ptr cmd = IMAPCommand::CAPABILITY(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "CAPABILITY", cmd->getText()); } - void testNOOP() - { + void testNOOP() { + vmime::shared_ptr cmd = IMAPCommand::NOOP(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "NOOP", cmd->getText()); } - void testEXPUNGE() - { + void testEXPUNGE() { + vmime::shared_ptr cmd = IMAPCommand::EXPUNGE(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "EXPUNGE", cmd->getText()); } - void testCLOSE() - { + void testCLOSE() { + vmime::shared_ptr cmd = IMAPCommand::CLOSE(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "CLOSE", cmd->getText()); } - void testLOGOUT() - { + void testLOGOUT() { + vmime::shared_ptr cmd = IMAPCommand::LOGOUT(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "LOGOUT", cmd->getText()); } - void testSend() - { - vmime::shared_ptr cmd = IMAPCommand::createCommand("MY_COMMAND param1 param2"); + void testSend() { + + vmime::shared_ptr cmd = + IMAPCommand::createCommand("MY_COMMAND param1 param2"); vmime::shared_ptr sess = vmime::net::session::create(); diff --git a/tests/net/imap/IMAPParserTest.cpp b/tests/net/imap/IMAPParserTest.cpp index 5d810a8f..974dc241 100644 --- a/tests/net/imap/IMAPParserTest.cpp +++ b/tests/net/imap/IMAPParserTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,8 +39,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) // For Apple iCloud IMAP server - void testExtraSpaceInCapaResponse() - { + void testExtraSpaceInCapaResponse() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); @@ -49,7 +49,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) socket->localSend( "* CAPABILITY IMAP4rev1 AUTH=ATOKEN AUTH=PLAIN \r\n" // extra space at end - "a001 OK Capability completed.\r\n"); + "a001 OK Capability completed.\r\n" + ); vmime::shared_ptr parser = vmime::make_shared (); @@ -65,15 +66,16 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) socket->localSend( "* CAPABILITY IMAP4rev1 AUTH=ATOKEN AUTH=PLAIN \r\n" // extra space at end - "a002 OK Capability completed.\r\n"); + "a002 OK Capability completed.\r\n" + ); parser->setStrict(true); VASSERT_THROW("strict mode", parser->readResponse(/* literalHandler */ NULL), vmime::exceptions::invalid_response); } // For Apple iCloud/Exchange IMAP server - void testContinueReqWithoutSpace() - { + void testContinueReqWithoutSpace() { + // continue_req ::= "+" SPACE (resp_text / base64) // // Some servers do not send SPACE when response text is empty. @@ -114,8 +116,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) // that is running the Exchange Server 2007 IMAP4 service, a corrupted // response is sent as a reply // --> http://support.microsoft.com/kb/975918/en-us - void testNILValueInBodyFldEnc() - { + void testNILValueInBodyFldEnc() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); @@ -145,13 +147,13 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) } // "body_fld_lang" is optional after "body_fld_dsp" in "body_ext_mpart" (Yahoo) - void testFETCHResponse_optional_body_fld_lang() - { + void testFETCHResponse_optional_body_fld_lang() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); vmime::shared_ptr tag = - vmime::make_shared (); + vmime::make_shared (); const char* resp = "* 1 FETCH (UID 7 RFC822.SIZE 694142 BODYSTRUCTURE (((\"text\" \"plain\" (\"charset\" \"utf-8\") NIL NIL \"7bit\" 0 0 NIL NIL NIL NIL)(\"text\" \"html\" (\"charset\" \"utf-8\") NIL NIL \"7bit\" 193 0 NIL NIL NIL NIL) \"alternative\" (\"boundary\" \"----=_Part_536_109505883.1410847112666\") NIL)(\"image\" \"jpeg\" NIL \"<4db20d0e-e9f8-729b-aaf7-688b5956d0bc@yahoo.com>\" NIL \"base64\" 351784 NIL (\"attachment\" (\"name\" \"att2\" \"filename\" \"9.jpg\")) NIL NIL)(\"image\" \"jpeg\" NIL \"<542417d7-c0ed-db72-f9fc-d9ab2c7e0a6f@yahoo.com>\" NIL \"base64\" 337676 NIL (\"attachment\" (\"name\" \"att3\" \"filename\" \"10.jpg\")) NIL NIL) \"mixed\" (\"boundary\" \"----=_Part_537_1371134700.1410847112668\") NIL) RFC822.HEADER {3}\r\nx\r\n)\r\na001 OK FETCH complete\r\n"; @@ -169,8 +171,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest) // Support for NIL boundary, for mail.ru IMAP server: // https://www.ietf.org/mail-archive/web/imapext/current/msg05442.html - void testFETCHBodyStructure_NIL_body_fld_param_value() - { + void testFETCHBodyStructure_NIL_body_fld_param_value() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); diff --git a/tests/net/imap/IMAPTagTest.cpp b/tests/net/imap/IMAPTagTest.cpp index db04537a..c8e09b6b 100644 --- a/tests/net/imap/IMAPTagTest.cpp +++ b/tests/net/imap/IMAPTagTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,16 +36,16 @@ VMIME_TEST_SUITE_BEGIN(imapTagTest) VMIME_TEST_LIST_END - void testConstruct() - { + void testConstruct() { + vmime::shared_ptr tag = vmime::make_shared (); VASSERT_EQ("init", "a001", static_cast (*tag)); } - void testIncrement() - { + void testIncrement() { + vmime::shared_ptr tag = vmime::make_shared (); @@ -59,13 +59,14 @@ VMIME_TEST_SUITE_BEGIN(imapTagTest) VASSERT_EQ("init", "a004", static_cast (*tag)); } - void testReset() - { + void testReset() { + vmime::shared_ptr tag = vmime::make_shared (); - for (int i = tag->number() ; i < tag->maximumNumber() ; ++i) + for (int i = tag->number() ; i < tag->maximumNumber() ; ++i) { (*tag)++; + } VASSERT_EQ("last", "Z999", static_cast (*tag)); @@ -74,13 +75,14 @@ VMIME_TEST_SUITE_BEGIN(imapTagTest) VASSERT_EQ("reset", "a001", static_cast (*tag)); } - void testNumber() - { + void testNumber() { + vmime::shared_ptr tag = vmime::make_shared (); - for (int i = 0 ; i < 41 ; ++i) + for (int i = 0 ; i < 41 ; ++i) { (*tag)++; + } VASSERT_EQ("number", 42, tag->number()); } diff --git a/tests/net/imap/IMAPUtilsTest.cpp b/tests/net/imap/IMAPUtilsTest.cpp index db88b539..b707fd06 100644 --- a/tests/net/imap/IMAPUtilsTest.cpp +++ b/tests/net/imap/IMAPUtilsTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2014 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,8 +46,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) VMIME_TEST_LIST_END - void testQuoteString() - { + void testQuoteString() { + VASSERT_EQ("unquoted", "ascii", IMAPUtils::quoteString("ascii")); VASSERT_EQ("space", "\"ascii with space\"", IMAPUtils::quoteString("ascii with space")); @@ -63,8 +63,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) } - void testToModifiedUTF7() - { + void testToModifiedUTF7() { + #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) // Example strings from RFC-1642 (modified for IMAP UTF-7) @@ -80,8 +80,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) #undef FC } - void testFromModifiedUTF7() - { + void testFromModifiedUTF7() { + #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) // Example strings from RFC-1642 (modified for IMAP UTF-7) @@ -97,8 +97,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) #undef FC } - void testConvertAddressList() - { + void testConvertAddressList() { + IMAPParser parser; IMAPParser::address_list addrList; @@ -117,8 +117,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) VASSERT_EQ("mbox-2", "name2", mboxList.getMailboxAt(1)->getName().getWholeBuffer()); } - void testMessageFlagList() - { + void testMessageFlagList() { + int flags = 0; std::vector flagList; @@ -158,14 +158,14 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) VASSERT("2.found2", std::find(flagList.begin(), flagList.end(), "\\Seen") != flagList.end()); } - void testDateTime() - { + void testDateTime() { + vmime::datetime dt(2014, 3, 17, 23, 26, 22, vmime::datetime::GMT2); VASSERT_EQ("datetime", "\"17-Mar-2014 23:26:22 +0200\"", IMAPUtils::dateTime(dt)); } - void testPathToString() - { + void testPathToString() { + #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) vmime::net::folder::path path; @@ -177,8 +177,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) #undef FC } - void testStringToPath() - { + void testStringToPath() { + #define FC(x) vmime::net::folder::path::component(x, vmime::charsets::UTF_8) vmime::net::folder::path path = IMAPUtils::stringToPath('/', "Hi Mum &Jjo-!/&ZeVnLIqe-"); @@ -190,8 +190,8 @@ VMIME_TEST_SUITE_BEGIN(IMAPUtilsTest) #undef FC } - void testBuildFetchCommand() - { + void testBuildFetchCommand() { + vmime::shared_ptr cnt; vmime::net::messageSet msgs = vmime::net::messageSet::byNumber(42); diff --git a/tests/net/maildir/maildirStoreTest.cpp b/tests/net/maildir/maildirStoreTest.cpp index 11868c9d..1f418e81 100644 --- a/tests/net/maildir/maildirStoreTest.cpp +++ b/tests/net/maildir/maildirStoreTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,8 @@ typedef vmime::net::folder::path fpath; typedef vmime::net::folder::path::component fpathc; -const fpath operator/(const fpath& path, const std::string& c) -{ +const fpath operator/(const fpath& path, const std::string& c) { + return path / fpathc(c); } @@ -65,8 +65,7 @@ static const vmime::string TEST_MESSAGE_1 = */ // KMail format -static const vmime::string TEST_MAILDIR_KMAIL[] = // directories to create -{ +static const vmime::string TEST_MAILDIR_KMAIL[] = { // directories to create "/Folder", "/Folder/new", "/Folder/tmp", @@ -92,15 +91,13 @@ static const vmime::string TEST_MAILDIR_KMAIL[] = // directories to create "*" // end }; -static const vmime::string TEST_MAILDIRFILES_KMAIL[] = // files to create and their contents -{ +static const vmime::string TEST_MAILDIRFILES_KMAIL[] = { // files to create and their contents "/.Folder.directory/.SubFolder.directory/SubSubFolder2/cur/1043236113.351.EmqD:S", TEST_MESSAGE_1, "*" // end }; // Courier format -static const vmime::string TEST_MAILDIR_COURIER[] = // directories to create -{ +static const vmime::string TEST_MAILDIR_COURIER[] = { // directories to create "/.Folder", "/.Folder/new", "/.Folder/tmp", @@ -125,8 +122,7 @@ static const vmime::string TEST_MAILDIR_COURIER[] = // directories to create "*" // end }; -static const vmime::string TEST_MAILDIRFILES_COURIER[] = // files to create and their contents -{ +static const vmime::string TEST_MAILDIRFILES_COURIER[] = { // files to create and their contents "/.Folder/maildirfolder", "", "/.Folder.SubFolder/maildirfolder", "", "/.Folder.SubFolder.SubSubFolder1/maildirfolder", "", @@ -169,22 +165,22 @@ VMIME_TEST_SUITE_BEGIN(maildirStoreTest) public: - maildirStoreTest() - { + maildirStoreTest() { + // Temporary directory m_tempPath = fspath() / fspathc("tmp") // Use /tmp / fspathc("vmime" + vmime::utility::stringUtils::toString(std::time(NULL)) + vmime::utility::stringUtils::toString(std::rand())); } - void tearDown() - { + void tearDown() { + // In case of an uncaught exception destroyMaildir(); } - void testDetectFormat_KMail() - { + void testDetectFormat_KMail() { + createMaildir(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); vmime::shared_ptr store = @@ -195,8 +191,8 @@ public: destroyMaildir(); } - void testDetectFormat_Courier() - { + void testDetectFormat_Courier() { + createMaildir(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); vmime::shared_ptr store = @@ -208,18 +204,18 @@ public: } - void testListRootFolders_KMail() - { + void testListRootFolders_KMail() { + testListRootFoldersImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testListRootFolders_Courier() - { + void testListRootFolders_Courier() { + testListRootFoldersImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testListRootFoldersImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testListRootFoldersImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); // Connect to store @@ -238,18 +234,18 @@ public: } - void testListAllFolders_KMail() - { + void testListAllFolders_KMail() { + testListAllFoldersImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testListAllFolders_Courier() - { + void testListAllFolders_Courier() { + testListAllFoldersImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testListAllFoldersImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testListAllFoldersImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); // Connect to store @@ -271,25 +267,26 @@ public: } - void testListMessages_KMail() - { + void testListMessages_KMail() { + testListMessagesImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testListMessages_Courier() - { + void testListMessages_Courier() { + testListMessagesImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testListMessagesImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testListMessagesImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); vmime::shared_ptr store = createAndConnectStore(); vmime::shared_ptr rootFolder = store->getRootFolder(); - vmime::shared_ptr folder = store->getFolder - (fpath() / "Folder" / "SubFolder" / "SubSubFolder2"); + vmime::shared_ptr folder = store->getFolder( + fpath() / "Folder" / "SubFolder" / "SubSubFolder2" + ); vmime::size_t count, unseen; folder->status(count, unseen); @@ -316,14 +313,14 @@ public: } - void testRenameFolder_KMail() - { - try - { + void testRenameFolder_KMail() { + + try { + testRenameFolderImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); - } - catch (vmime::exception& e) - { + + } catch (vmime::exception& e) { + std::cerr << e; throw e; } @@ -331,27 +328,27 @@ public: void testRenameFolder_Courier() { - try - { + try { + testRenameFolderImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); - } - catch (vmime::exception& e) - { + + } catch (vmime::exception& e) { + std::cerr << e; throw e; } } - void testRenameFolderImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testRenameFolderImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); vmime::shared_ptr store = createAndConnectStore(); vmime::shared_ptr rootFolder = store->getRootFolder(); // Rename "Folder/SubFolder" to "Folder/foo" - vmime::shared_ptr folder = store->getFolder - (fpath() / "Folder" / "SubFolder"); + vmime::shared_ptr folder = + store->getFolder(fpath() / "Folder" / "SubFolder"); folder->rename(fpath() / "Folder" / "foo"); @@ -373,26 +370,26 @@ public: } - void testDestroyFolder_KMail() - { + void testDestroyFolder_KMail() { + testDestroyFolderImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testDestroyFolder_Courier() - { + void testDestroyFolder_Courier() { + testDestroyFolderImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testDestroyFolderImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testDestroyFolderImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); vmime::shared_ptr store = createAndConnectStore(); vmime::shared_ptr rootFolder = store->getRootFolder(); // Destroy "Folder/SubFolder" (total: 3 folders) - vmime::shared_ptr folder = store->getFolder - (fpath() / "Folder" / "SubFolder"); + vmime::shared_ptr folder = + store->getFolder(fpath() / "Folder" / "SubFolder"); folder->destroy(); @@ -411,18 +408,18 @@ public: } - void testFolderExists_KMail() - { + void testFolderExists_KMail() { + testFolderExistsImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testFolderExists_Courier() - { + void testFolderExists_Courier() { + testFolderExistsImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testFolderExistsImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testFolderExistsImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); vmime::shared_ptr store = createAndConnectStore(); @@ -437,18 +434,18 @@ public: } - void testCreateFolder_KMail() - { + void testCreateFolder_KMail() { + testCreateFolderImpl(TEST_MAILDIR_KMAIL, TEST_MAILDIRFILES_KMAIL); } - void testCreateFolder_Courier() - { + void testCreateFolder_Courier() { + testCreateFolderImpl(TEST_MAILDIR_COURIER, TEST_MAILDIRFILES_COURIER); } - void testCreateFolderImpl(const vmime::string* const dirs, const vmime::string* const files) - { + void testCreateFolderImpl(const vmime::string* const dirs, const vmime::string* const files) { + createMaildir(dirs, files); vmime::shared_ptr store = createAndConnectStore(); @@ -471,8 +468,8 @@ private: vmime::utility::file::path m_tempPath; - vmime::shared_ptr createAndConnectStore() - { + vmime::shared_ptr createAndConnectStore() { + vmime::shared_ptr session = vmime::net::session::create(); vmime::shared_ptr store = @@ -483,21 +480,23 @@ private: return store; } - const vmime::shared_ptr findFolder - (const std::vector >& folders, - const vmime::net::folder::path& path) - { - for (size_t i = 0, n = folders.size() ; i < n ; ++i) - { - if (folders[i]->getFullPath() == path) + const vmime::shared_ptr findFolder( + const std::vector >& folders, + const vmime::net::folder::path& path + ) { + + for (size_t i = 0, n = folders.size() ; i < n ; ++i) { + + if (folders[i]->getFullPath() == path) { return folders[i]; + } } return vmime::null; } - const vmime::utility::url getStoreURL() - { + const vmime::utility::url getStoreURL() { + vmime::shared_ptr fsf = vmime::platform::getHandler()->getFileSystemFactory(); @@ -507,22 +506,22 @@ private: return url; } - void createMaildir(const vmime::string* const dirs, const vmime::string* const files) - { + void createMaildir(const vmime::string* const dirs, const vmime::string* const files) { + vmime::shared_ptr fsf = vmime::platform::getHandler()->getFileSystemFactory(); vmime::shared_ptr rootDir = fsf->create(m_tempPath); rootDir->createDirectory(false); - for (vmime::string const* dir = dirs ; *dir != "*" ; ++dir) - { + for (vmime::string const* dir = dirs ; *dir != "*" ; ++dir) { + vmime::shared_ptr fdir = fsf->create(m_tempPath / fsf->stringToPath(*dir)); fdir->createDirectory(false); } - for (vmime::string const* file = files ; *file != "*" ; file += 2) - { + for (vmime::string const* file = files ; *file != "*" ; file += 2) { + const vmime::string& contents = *(file + 1); vmime::shared_ptr ffile = fsf->create(m_tempPath / fsf->stringToPath(*file)); @@ -539,53 +538,47 @@ private: } - void destroyMaildir() - { + void destroyMaildir() { + vmime::shared_ptr fsf = vmime::platform::getHandler()->getFileSystemFactory(); recursiveDelete(fsf->create(m_tempPath)); } - void recursiveDelete(vmime::shared_ptr dir) - { - if (!dir->exists() || !dir->isDirectory()) + void recursiveDelete(vmime::shared_ptr dir) { + + if (!dir->exists() || !dir->isDirectory()) { return; + } vmime::shared_ptr files = dir->getFiles(); // First, delete files and subdirectories in this directory - while (files->hasMoreElements()) - { + while (files->hasMoreElements()) { + vmime::shared_ptr file = files->nextElement(); - if (file->isDirectory()) - { + if (file->isDirectory()) { + recursiveDelete(file); - } - else - { - try - { + + } else { + + try { file->remove(); - } - catch (vmime::exceptions::filesystem_exception&) - { + } catch (vmime::exceptions::filesystem_exception&) { // Ignore } } } // Then, delete this (empty) directory - try - { + try { dir->remove(); - } - catch (vmime::exceptions::filesystem_exception&) - { + } catch (vmime::exceptions::filesystem_exception&) { // Ignore } } VMIME_TEST_SUITE_END - diff --git a/tests/net/maildir/maildirUtilsTest.cpp b/tests/net/maildir/maildirUtilsTest.cpp index 3538d4a8..9deeebfa 100644 --- a/tests/net/maildir/maildirUtilsTest.cpp +++ b/tests/net/maildir/maildirUtilsTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,11 +36,13 @@ VMIME_TEST_SUITE_BEGIN(maildirUtilsTest) VMIME_TEST_LIST_END - void testMessageSetToNumberList() - { + void testMessageSetToNumberList() { + const std::vector msgNums = - maildirUtils::messageSetToNumberList - (vmime::net::messageSet::byNumber(5, -1), /* msgCount */ 8); + maildirUtils::messageSetToNumberList( + vmime::net::messageSet::byNumber(5, -1), + /* msgCount */ 8 + ); VASSERT_EQ("Count", 4, msgNums.size()); VASSERT_EQ("1", 5, msgNums[0]); @@ -50,4 +52,3 @@ VMIME_TEST_SUITE_BEGIN(maildirUtilsTest) } VMIME_TEST_SUITE_END - diff --git a/tests/net/messageSetTest.cpp b/tests/net/messageSetTest.cpp index 4d129663..dee5dc81 100644 --- a/tests/net/messageSetTest.cpp +++ b/tests/net/messageSetTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,47 +46,51 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) VMIME_TEST_LIST_END - class messageSetStringEnumerator : public vmime::net::messageSetEnumerator - { + class messageSetStringEnumerator : public vmime::net::messageSetEnumerator { + public: messageSetStringEnumerator() - : m_first(true) - { + : m_first(true) { + } - void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) - { - if (!m_first) - m_oss << ","; + void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) { - if (range.getFirst() == range.getLast()) + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { m_oss << range.getFirst(); - else if (range.getLast() == size_t(-1)) + } else if (range.getLast() == size_t(-1)) { m_oss << range.getFirst() << ":(LAST)"; - else + } else { m_oss << range.getFirst() << ":" << range.getLast(); + } m_first = false; } - void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) - { - if (!m_first) - m_oss << ","; + void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) { - if (range.getFirst() == range.getLast()) + if (!m_first) { + m_oss << ","; + } + + if (range.getFirst() == range.getLast()) { m_oss << range.getFirst(); - else if (range.getLast() == size_t(-1)) + } else if (range.getLast() == size_t(-1)) { m_oss << range.getFirst() << ":(LAST)"; - else + } else { m_oss << range.getFirst() << ":" << range.getLast(); + } m_first = false; } - const std::string str() const - { + const std::string str() const { + return m_oss.str(); } @@ -97,8 +101,8 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) }; - const std::string enumerateAsString(const vmime::net::messageSet& set) - { + const std::string enumerateAsString(const vmime::net::messageSet& set) { + messageSetStringEnumerator en; set.enumerate(en); @@ -106,33 +110,33 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) } - void testNumberSet_Single() - { + void testNumberSet_Single() { + VASSERT_EQ("str", "42", enumerateAsString(vmime::net::messageSet::byNumber(42))); } - void testNumberSet_Range() - { + void testNumberSet_Range() { + VASSERT_EQ("str", "42:100", enumerateAsString(vmime::net::messageSet::byNumber(42, 100))); } - void testNumberSet_InvalidRange() - { + void testNumberSet_InvalidRange() { + VASSERT_THROW("first > last", vmime::net::messageSet::byNumber(100, 42), std::invalid_argument); } - void testNumberSet_InvalidFirst() - { + void testNumberSet_InvalidFirst() { + VASSERT_THROW("first == -1", vmime::net::messageSet::byNumber(-1, 42), std::invalid_argument); } - void testNumberSet_InfiniteRange() - { + void testNumberSet_InfiniteRange() { + VASSERT_EQ("str", "42:(LAST)", enumerateAsString(vmime::net::messageSet::byNumber(42, -1))); } - void testNumberSet_Multiple() - { + void testNumberSet_Multiple() { + std::vector numbers; numbers.push_back(1); // test grouping 1:3 numbers.push_back(89); // test sorting @@ -151,23 +155,23 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) } - void testUIDSet_Single() - { + void testUIDSet_Single() { + VASSERT_EQ("str", "abcdef", enumerateAsString(vmime::net::messageSet::byUID("abcdef"))); } - void testUIDSet_Range() - { + void testUIDSet_Range() { + VASSERT_EQ("str", "abc:def", enumerateAsString(vmime::net::messageSet::byUID("abc:def"))); } - void testUIDSet_InfiniteRange() - { + void testUIDSet_InfiniteRange() { + VASSERT_EQ("str", "abc:*", enumerateAsString(vmime::net::messageSet::byUID("abc", "*"))); } - void testUIDSet_MultipleNumeric() - { + void testUIDSet_MultipleNumeric() { + std::vector uids; uids.push_back("1"); // test grouping 1:3 uids.push_back("89"); // test sorting @@ -185,8 +189,8 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) VASSERT_EQ("str", "1:3,42,53:57,89,99", enumerateAsString(vmime::net::messageSet::byUID(uids))); } - void testUIDSet_MultipleNonNumeric() - { + void testUIDSet_MultipleNonNumeric() { + std::vector uids; uids.push_back("12"); uids.push_back("34"); @@ -196,8 +200,8 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) VASSERT_EQ("str", "12,34,ab56,78cd", enumerateAsString(vmime::net::messageSet::byUID(uids))); } - void testIsNumberSet() - { + void testIsNumberSet() { + VASSERT_TRUE("number1", vmime::net::messageSet::byNumber(42).isNumberSet()); VASSERT_FALSE("uid1", vmime::net::messageSet::byUID("42").isNumberSet()); @@ -205,8 +209,8 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) VASSERT_FALSE("uid2", vmime::net::messageSet::byUID("42", "*").isNumberSet()); } - void testIsUIDSet() - { + void testIsUIDSet() { + VASSERT_FALSE("number1", vmime::net::messageSet::byNumber(42).isUIDSet()); VASSERT_TRUE("uid1", vmime::net::messageSet::byUID("42").isUIDSet()); @@ -214,8 +218,8 @@ VMIME_TEST_SUITE_BEGIN(messageSetTest) VASSERT_TRUE("uid2", vmime::net::messageSet::byUID("42", "*").isUIDSet()); } - void testMixedRanges() - { + void testMixedRanges() { + vmime::net::messageSet set = vmime::net::messageSet::byNumber(1, 5); set.addRange(vmime::net::numberMessageRange(6, 8)); diff --git a/tests/net/pop3/POP3CommandTest.cpp b/tests/net/pop3/POP3CommandTest.cpp index 139e948b..3ed579ee 100644 --- a/tests/net/pop3/POP3CommandTest.cpp +++ b/tests/net/pop3/POP3CommandTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -58,174 +58,177 @@ VMIME_TEST_SUITE_BEGIN(POP3CommandTest) VMIME_TEST_LIST_END - void testCreateCommand() - { + void testCreateCommand() { + vmime::shared_ptr cmd = POP3Command::createCommand("MY_COMMAND"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND", cmd->getText()); } - void testCreateCommandParams() - { + void testCreateCommandParams() { + vmime::shared_ptr cmd = POP3Command::createCommand("MY_COMMAND param1 param2"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND param1 param2", cmd->getText()); } - void testCAPA() - { + void testCAPA() { + vmime::shared_ptr cmd = POP3Command::CAPA(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "CAPA", cmd->getText()); } - void testNOOP() - { + void testNOOP() { + vmime::shared_ptr cmd = POP3Command::NOOP(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "NOOP", cmd->getText()); } - void testAUTH() - { + void testAUTH() { + vmime::shared_ptr cmd = POP3Command::AUTH("saslmechanism"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTH saslmechanism", cmd->getText()); } - void testAUTH_InitialResponse() - { + void testAUTH_InitialResponse() { + vmime::shared_ptr cmd = POP3Command::AUTH("saslmechanism", "initial-response"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTH saslmechanism initial-response", cmd->getText()); } - void testSTLS() - { + void testSTLS() { + vmime::shared_ptr cmd = POP3Command::STLS(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "STLS", cmd->getText()); } - void testAPOP() - { + void testAPOP() { + vmime::shared_ptr cmd = POP3Command::APOP("user", "digest"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "APOP user digest", cmd->getText()); } - void testUSER() - { + void testUSER() { + vmime::shared_ptr cmd = POP3Command::USER("user"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "USER user", cmd->getText()); } - void testPASS() - { + void testPASS() { + vmime::shared_ptr cmd = POP3Command::PASS("pass"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "PASS pass", cmd->getText()); } - void testSTAT() - { + void testSTAT() { + vmime::shared_ptr cmd = POP3Command::STAT(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "STAT", cmd->getText()); } - void testLIST() - { + void testLIST() { + vmime::shared_ptr cmd = POP3Command::LIST(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "LIST", cmd->getText()); } - void testLISTMessage() - { + void testLISTMessage() { + vmime::shared_ptr cmd = POP3Command::LIST(42); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "LIST 42", cmd->getText()); } - void testUIDL() - { + void testUIDL() { + vmime::shared_ptr cmd = POP3Command::UIDL(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "UIDL", cmd->getText()); } - void testUIDLMessage() - { + void testUIDLMessage() { + vmime::shared_ptr cmd = POP3Command::UIDL(42); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "UIDL 42", cmd->getText()); } - void testDELE() - { + void testDELE() { + vmime::shared_ptr cmd = POP3Command::DELE(42); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "DELE 42", cmd->getText()); } - void testRETR() - { + void testRETR() { + vmime::shared_ptr cmd = POP3Command::RETR(42); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RETR 42", cmd->getText()); } - void testTOP() - { + void testTOP() { + vmime::shared_ptr cmd = POP3Command::TOP(42, 567); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "TOP 42 567", cmd->getText()); } - void testRSET() - { + void testRSET() { + vmime::shared_ptr cmd = POP3Command::RSET(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RSET", cmd->getText()); } - void testQUIT() - { + void testQUIT() { + vmime::shared_ptr cmd = POP3Command::QUIT(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "QUIT", cmd->getText()); } - void testWriteToSocket() - { + void testWriteToSocket() { + vmime::shared_ptr cmd = POP3Command::createCommand("MY_COMMAND param1 param2"); vmime::shared_ptr sok = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (sok), - vmime::shared_ptr ()); + + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (sok), + vmime::shared_ptr () + ); cmd->send(conn); diff --git a/tests/net/pop3/POP3ResponseTest.cpp b/tests/net/pop3/POP3ResponseTest.cpp index 2d3b3d32..8fecb749 100644 --- a/tests/net/pop3/POP3ResponseTest.cpp +++ b/tests/net/pop3/POP3ResponseTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,13 +45,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VMIME_TEST_LIST_END - void testSingleLineResponseOK() - { + void testSingleLineResponseOK() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Response Text\r\n"); @@ -65,13 +67,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("First Line", "+OK Response Text", resp->getFirstLine()); } - void testSingleLineResponseERR() - { + void testSingleLineResponseERR() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("-ERR Response Text\r\n"); @@ -85,13 +89,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("First Line", "-ERR Response Text", resp->getFirstLine()); } - void testSingleLineResponseReady() - { + void testSingleLineResponseReady() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+ challenge_string\r\n"); @@ -105,8 +111,8 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("First Line", "+ challenge_string", resp->getFirstLine()); } - void testSingleLineResponseInvalid() - { + void testSingleLineResponseInvalid() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); @@ -125,13 +131,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("First Line", "Invalid Response Text", resp->getFirstLine()); } - void testSingleLineResponseLF() - { + void testSingleLineResponseLF() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Response terminated by LF\n"); @@ -145,13 +153,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("First Line", "+OK Response terminated by LF", resp->getFirstLine()); } - void testMultiLineResponse() - { + void testMultiLineResponse() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Response Text\r\n"); socket->localSend("Line 1\r\n"); @@ -170,13 +180,15 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("Line 2", "Line 2", resp->getLineAt(1)); } - void testMultiLineResponseLF() - { + void testMultiLineResponseLF() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Response Text\n"); socket->localSend("Line 1\n"); @@ -195,18 +207,21 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) VASSERT_EQ("Line 2", "Line 2", resp->getLineAt(1)); } - void testLargeResponse() - { + void testLargeResponse() { + std::ostringstream data; - for (unsigned int i = 0 ; i < 5000 ; ++i) + for (unsigned int i = 0 ; i < 5000 ; ++i) { data << "VMIME.VMIME\nVMIME\r\nVMIME_VMIME"; + } vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Large Response Follows\n"); socket->localSend(data.str()); @@ -227,4 +242,3 @@ VMIME_TEST_SUITE_BEGIN(POP3ResponseTest) } VMIME_TEST_SUITE_END - diff --git a/tests/net/pop3/POP3StoreTest.cpp b/tests/net/pop3/POP3StoreTest.cpp index a6818d46..5d9e3c20 100644 --- a/tests/net/pop3/POP3StoreTest.cpp +++ b/tests/net/pop3/POP3StoreTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -37,8 +37,8 @@ VMIME_TEST_SUITE_BEGIN(POP3StoreTest) VMIME_TEST_LIST_END - void testCreateFromURL() - { + void testCreateFromURL() { + vmime::shared_ptr sess = vmime::net::session::create(); // POP3 @@ -54,8 +54,8 @@ VMIME_TEST_SUITE_BEGIN(POP3StoreTest) VASSERT_TRUE("pop3s", typeid(*store2) == typeid(vmime::net::pop3::POP3SStore)); } - void testConnectToInvalidServer() - { + void testConnectToInvalidServer() { + vmime::shared_ptr sess = vmime::net::session::create(); vmime::utility::url url("pop3://invalid-pop3-server"); diff --git a/tests/net/pop3/POP3TestUtils.hpp b/tests/net/pop3/POP3TestUtils.hpp index b0ec09b8..24efb8b3 100644 --- a/tests/net/pop3/POP3TestUtils.hpp +++ b/tests/net/pop3/POP3TestUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -25,37 +25,40 @@ #include "vmime/net/pop3/POP3Store.hpp" -class POP3TestStore : public vmime::net::pop3::POP3Store -{ +class POP3TestStore : public vmime::net::pop3::POP3Store { + public: POP3TestStore() : POP3Store(vmime::net::session::create(), - vmime::shared_ptr ()) - { + vmime::shared_ptr ()) { + } }; -class POP3ConnectionTest : public vmime::net::pop3::POP3Connection -{ +class POP3ConnectionTest : public vmime::net::pop3::POP3Connection { + public: - POP3ConnectionTest(vmime::shared_ptr socket, - vmime::shared_ptr timeoutHandler) + POP3ConnectionTest( + vmime::shared_ptr socket, + vmime::shared_ptr timeoutHandler + ) : POP3Connection(vmime::make_shared (), vmime::shared_ptr ()), - m_socket(socket), m_timeoutHandler(timeoutHandler) - { + m_socket(socket), + m_timeoutHandler(timeoutHandler) { + } - vmime::shared_ptr getSocket() - { + vmime::shared_ptr getSocket() { + return m_socket; } - vmime::shared_ptr getTimeoutHandler() - { + vmime::shared_ptr getTimeoutHandler() { + return m_timeoutHandler; } diff --git a/tests/net/pop3/POP3UtilsTest.cpp b/tests/net/pop3/POP3UtilsTest.cpp index 36029eaa..1cded39b 100644 --- a/tests/net/pop3/POP3UtilsTest.cpp +++ b/tests/net/pop3/POP3UtilsTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,13 +40,15 @@ VMIME_TEST_SUITE_BEGIN(POP3UtilsTest) VMIME_TEST_LIST_END - void testParseMultiListOrUidlResponse() - { + void testParseMultiListOrUidlResponse() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::shared_ptr toh = vmime::make_shared (); - vmime::shared_ptr conn = vmime::make_shared - (vmime::dynamicCast (socket), toh); + vmime::shared_ptr conn = + vmime::make_shared ( + vmime::dynamicCast (socket), toh + ); socket->localSend("+OK Response Text\r\n"); socket->localSend("1 abcdef\r\n"); @@ -70,11 +72,11 @@ VMIME_TEST_SUITE_BEGIN(POP3UtilsTest) VASSERT_EQ("5 (with extra space)", "yz", result[8]); } - void testMessageSetToNumberList() - { - const std::vector msgNums = - POP3Utils::messageSetToNumberList - (vmime::net::messageSet::byNumber(5, -1), /* msgCount */ 8); + void testMessageSetToNumberList() { + + const std::vector msgNums = POP3Utils::messageSetToNumberList( + vmime::net::messageSet::byNumber(5, -1), /* msgCount */ 8 + ); VASSERT_EQ("Count", 4, msgNums.size()); VASSERT_EQ("1", 5, msgNums[0]); @@ -84,4 +86,3 @@ VMIME_TEST_SUITE_BEGIN(POP3UtilsTest) } VMIME_TEST_SUITE_END - diff --git a/tests/net/smtp/SMTPCommandSetTest.cpp b/tests/net/smtp/SMTPCommandSetTest.cpp index f419eb40..7ea3578b 100644 --- a/tests/net/smtp/SMTPCommandSetTest.cpp +++ b/tests/net/smtp/SMTPCommandSetTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,24 +44,24 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VMIME_TEST_LIST_END - void testCreate() - { + void testCreate() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ false); VASSERT_NOT_NULL("Not null", cset); VASSERT_FALSE("Finished", cset->isFinished()); } - void testCreatePipeline() - { + void testCreatePipeline() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ true); VASSERT_NOT_NULL("Not null", cset); VASSERT_FALSE("Finished", cset->isFinished()); } - void testAddCommand() - { + void testAddCommand() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ false); VASSERT_NO_THROW("No throw 1", cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1"))); @@ -82,8 +82,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VASSERT_TRUE("Finished", cset->isFinished()); } - void testAddCommandPipeline() - { + void testAddCommandPipeline() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ true); VASSERT_NO_THROW("No throw 1", cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1"))); @@ -105,8 +105,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VASSERT_THROW("Throw", cset->addCommand(SMTPCommand::createCommand("MY_COMMAND3")), std::runtime_error); } - void testWriteToSocket() - { + void testWriteToSocket() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ false); cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1")); @@ -127,8 +127,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VASSERT_EQ("Receive cmd 2", "MY_COMMAND2\r\n", response); } - void testWriteToSocketPipeline() - { + void testWriteToSocketPipeline() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ true); cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1")); @@ -144,8 +144,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VASSERT_EQ("Receive cmds", "MY_COMMAND1\r\nMY_COMMAND2\r\n", response); } - void testGetLastCommandSent() - { + void testGetLastCommandSent() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ false); cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1")); @@ -161,8 +161,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest) VASSERT_EQ("Cmd 2", "MY_COMMAND2", cset->getLastCommandSent()->getText()); } - void testGetLastCommandSentPipeline() - { + void testGetLastCommandSentPipeline() { + vmime::shared_ptr cset = SMTPCommandSet::create(/* pipelining */ true); cset->addCommand(SMTPCommand::createCommand("MY_COMMAND1")); diff --git a/tests/net/smtp/SMTPCommandTest.cpp b/tests/net/smtp/SMTPCommandTest.cpp index 9b3daa73..a0f03bb6 100644 --- a/tests/net/smtp/SMTPCommandTest.cpp +++ b/tests/net/smtp/SMTPCommandTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -56,150 +56,157 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) VMIME_TEST_LIST_END - void testCreateCommand() - { + void testCreateCommand() { + vmime::shared_ptr cmd = SMTPCommand::createCommand("MY_COMMAND"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND", cmd->getText()); } - void testCreateCommandParams() - { + void testCreateCommandParams() { + vmime::shared_ptr cmd = SMTPCommand::createCommand("MY_COMMAND param1 param2"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MY_COMMAND param1 param2", cmd->getText()); } - void testHELO() - { + void testHELO() { + vmime::shared_ptr cmd = SMTPCommand::HELO("hostname"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "HELO hostname", cmd->getText()); } - void testEHLO() - { + void testEHLO() { + vmime::shared_ptr cmd = SMTPCommand::EHLO("hostname"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "EHLO hostname", cmd->getText()); } - void testAUTH() - { + void testAUTH() { + vmime::shared_ptr cmd = SMTPCommand::AUTH("saslmechanism"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTH saslmechanism", cmd->getText()); } - void testAUTH_InitialResponse() - { + void testAUTH_InitialResponse() { + vmime::shared_ptr cmd = SMTPCommand::AUTH("saslmechanism", "initial-response"); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "AUTH saslmechanism initial-response", cmd->getText()); } - void testSTARTTLS() - { + void testSTARTTLS() { + vmime::shared_ptr cmd = SMTPCommand::STARTTLS(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "STARTTLS", cmd->getText()); } - void testMAIL() - { + void testMAIL() { + vmime::shared_ptr cmd = SMTPCommand::MAIL(vmime::mailbox("me@vmime.org"), false); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM:", cmd->getText()); } - void testMAIL_Encoded() - { - vmime::shared_ptr cmd = SMTPCommand::MAIL - (vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false); + void testMAIL_Encoded() { + + vmime::shared_ptr cmd = SMTPCommand::MAIL( + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM:", cmd->getText()); } - void testMAIL_UTF8() - { - vmime::shared_ptr cmd = SMTPCommand::MAIL - (vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true); + void testMAIL_UTF8() { + + vmime::shared_ptr cmd = SMTPCommand::MAIL( + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM: SMTPUTF8", cmd->getText()); } - void testMAIL_SIZE() - { - vmime::shared_ptr cmd = SMTPCommand::MAIL - (vmime::mailbox("me@vmime.org"), false, 123456789); + void testMAIL_SIZE() { + + vmime::shared_ptr cmd = SMTPCommand::MAIL( + vmime::mailbox("me@vmime.org"), false, 123456789 + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM: SIZE=123456789", cmd->getText()); } - void testMAIL_SIZE_UTF8() - { - vmime::shared_ptr cmd = SMTPCommand::MAIL - (vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, 123456789); + void testMAIL_SIZE_UTF8() { + + vmime::shared_ptr cmd = SMTPCommand::MAIL( + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true, 123456789 + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "MAIL FROM: SMTPUTF8 SIZE=123456789", cmd->getText()); } - void testRCPT() - { - vmime::shared_ptr cmd = SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org"), false); + void testRCPT() { + + vmime::shared_ptr cmd = + SMTPCommand::RCPT(vmime::mailbox("someone@vmime.org"), false); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RCPT TO:", cmd->getText()); } - void testRCPT_Encoded() - { - vmime::shared_ptr cmd = SMTPCommand::RCPT - (vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false); + void testRCPT_Encoded() { + + vmime::shared_ptr cmd = SMTPCommand::RCPT( + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), false + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RCPT TO:", cmd->getText()); } - void testRCPT_UTF8() - { - vmime::shared_ptr cmd = SMTPCommand::RCPT - (vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true); + void testRCPT_UTF8() { + + vmime::shared_ptr cmd = SMTPCommand::RCPT( + vmime::mailbox(vmime::emailAddress("mailtest", "例え.テスト")), true + ); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RCPT TO:", cmd->getText()); } - void testRSET() - { + void testRSET() { + vmime::shared_ptr cmd = SMTPCommand::RSET(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "RSET", cmd->getText()); } - void testDATA() - { + void testDATA() { + vmime::shared_ptr cmd = SMTPCommand::DATA(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "DATA", cmd->getText()); } - void testBDAT() - { + void testBDAT() { + vmime::shared_ptr cmd1 = SMTPCommand::BDAT(12345, false); VASSERT_NOT_NULL("Not null", cmd1); @@ -211,24 +218,24 @@ VMIME_TEST_SUITE_BEGIN(SMTPCommandTest) VASSERT_EQ("Text", "BDAT 67890 LAST", cmd2->getText()); } - void testNOOP() - { + void testNOOP() { + vmime::shared_ptr cmd = SMTPCommand::NOOP(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "NOOP", cmd->getText()); } - void testQUIT() - { + void testQUIT() { + vmime::shared_ptr cmd = SMTPCommand::QUIT(); VASSERT_NOT_NULL("Not null", cmd); VASSERT_EQ("Text", "QUIT", cmd->getText()); } - void testWriteToSocket() - { + void testWriteToSocket() { + vmime::shared_ptr cmd = SMTPCommand::createCommand("MY_COMMAND param1 param2"); vmime::shared_ptr tracer; diff --git a/tests/net/smtp/SMTPResponseTest.cpp b/tests/net/smtp/SMTPResponseTest.cpp index d47e31e9..f899a828 100644 --- a/tests/net/smtp/SMTPResponseTest.cpp +++ b/tests/net/smtp/SMTPResponseTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,12 +41,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VMIME_TEST_LIST_END - void testSingleLineResponse() - { + void testSingleLineResponse() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); socket->localSend("123 Response Text\r\n"); @@ -60,12 +59,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Text", "Response Text", resp->getText()); } - void testSingleLineResponseLF() - { + void testSingleLineResponseLF() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); socket->localSend("123 Response Text\n"); @@ -79,15 +77,13 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Text", "Response Text", resp->getText()); } - void testMultiLineResponse() - { + void testMultiLineResponse() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); - socket->localSend - ( + socket->localSend( "123-Response\r\n" "123 Text\r\n" ); @@ -108,15 +104,13 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Text", "Text", resp->getLineAt(1).getText()); } - void testMultiLineResponseDifferentCode() - { + void testMultiLineResponseDifferentCode() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); - socket->localSend - ( + socket->localSend( "123-Response\r\n" "456 Text\r\n" ); @@ -137,15 +131,13 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Text", "Text", resp->getLineAt(1).getText()); } - void testIncompleteMultiLineResponse() - { + void testIncompleteMultiLineResponse() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (1); + vmime::shared_ptr toh = vmime::make_shared (1); - socket->localSend - ( + socket->localSend( "123-Response\r\n" "123-Text\r\n" // Missing data @@ -153,20 +145,20 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) vmime::net::smtp::SMTPResponse::state responseState; - VASSERT_THROW("Incomplete response", + VASSERT_THROW( + "Incomplete response", vmime::net::smtp::SMTPResponse::readResponse(tracer, socket, toh, responseState), - vmime::exceptions::operation_timed_out); + vmime::exceptions::operation_timed_out + ); } - void testNoResponseText() - { + void testNoResponseText() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (1); + vmime::shared_ptr toh = vmime::make_shared (1); - socket->localSend - ( + socket->localSend( "250\r\n" ); @@ -180,12 +172,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Text", "", resp->getText()); } - void testEnhancedStatusCode() - { + void testEnhancedStatusCode() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); socket->localSend("250 2.1.5 OK fu13sm4720601wic.7 - gsmtp\r\n"); @@ -202,12 +193,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Enh.detail", 5, resp->getEnhancedCode().detail); } - void testNoEnhancedStatusCode() - { + void testNoEnhancedStatusCode() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); socket->localSend("354 Go ahead fu13sm4720601wic.7 - gsmtp\r\n"); @@ -224,12 +214,11 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) VASSERT_EQ("Enh.detail", 0, resp->getEnhancedCode().detail); } - void testInvalidEnhancedStatusCode() - { + void testInvalidEnhancedStatusCode() { + vmime::shared_ptr tracer; vmime::shared_ptr socket = vmime::make_shared (); - vmime::shared_ptr toh = - vmime::make_shared (); + vmime::shared_ptr toh = vmime::make_shared (); socket->localSend("250 4.2 xxx\r\n"); @@ -247,4 +236,3 @@ VMIME_TEST_SUITE_BEGIN(SMTPResponseTest) } VMIME_TEST_SUITE_END - diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp index cbfab4f5..8ea4ba75 100644 --- a/tests/net/smtp/SMTPTransportTest.cpp +++ b/tests/net/smtp/SMTPTransportTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,21 +33,19 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VMIME_TEST_LIST_BEGIN -/* VMIME_TEST(testConnectToInvalidServer) VMIME_TEST(testGreetingError) VMIME_TEST(testMAILandRCPT) VMIME_TEST(testChunking) VMIME_TEST(testSize_Chunking) VMIME_TEST(testSize_NoChunking) -*/ VMIME_TEST(testSMTPUTF8_available) VMIME_TEST(testSMTPUTF8_notAvailable) VMIME_TEST_LIST_END - void testConnectToInvalidServer() - { + void testConnectToInvalidServer() { + vmime::shared_ptr sess = vmime::net::session::create(); vmime::utility::url url("smtp://invalid-smtp-server"); @@ -56,26 +54,29 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) VASSERT_THROW("connect", store->connect(), vmime::exceptions::connection_error); } - void testGreetingError() - { + void testGreetingError() { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); - VASSERT_THROW("Connection", tr->connect(), - vmime::exceptions::connection_greeting_error); + VASSERT_THROW( + "Connection", + tr->connect(), + vmime::exceptions::connection_greeting_error + ); } - void testMAILandRCPT() - { + void testMAILandRCPT() { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); @@ -95,20 +96,22 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) tr->send(exp, recips, is, 0); } - void testChunking() - { + void testChunking() { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); tr->connect(); - VASSERT("Test server should report it supports the CHUNKING extension!", - vmime::dynamicCast (tr)->getConnection()->hasExtension("CHUNKING")); + VASSERT( + "Test server should report it supports the CHUNKING extension!", + vmime::dynamicCast (tr)->getConnection()->hasExtension("CHUNKING") + ); vmime::mailbox exp("expeditor@test.vmime.org"); @@ -120,20 +123,22 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) tr->send(msg, exp, recips); } - void testSize_Chunking() - { + void testSize_Chunking() { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); tr->connect(); - VASSERT("Test server should report it supports the SIZE extension!", - vmime::dynamicCast (tr)->getConnection()->hasExtension("SIZE")); + VASSERT( + "Test server should report it supports the SIZE extension!", + vmime::dynamicCast (tr)->getConnection()->hasExtension("SIZE") + ); vmime::mailbox exp("expeditor@test.vmime.org"); @@ -142,24 +147,29 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) vmime::shared_ptr msg = vmime::make_shared (); - VASSERT_THROW("Connection", tr->send(msg, exp, recips), - vmime::net::smtp::SMTPMessageSizeExceedsMaxLimitsException); + VASSERT_THROW( + "Max size limit exception", + tr->send(msg, exp, recips), + vmime::net::smtp::SMTPMessageSizeExceedsMaxLimitsException + ); } - void testSize_NoChunking() - { + void testSize_NoChunking() { + vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); tr->connect(); - VASSERT("Test server should report it supports the SIZE extension!", - vmime::dynamicCast (tr)->getConnection()->hasExtension("SIZE")); + VASSERT( + "Test server should report it supports the SIZE extension!", + vmime::dynamicCast (tr)->getConnection()->hasExtension("SIZE") + ); vmime::mailbox exp("expeditor@test.vmime.org"); @@ -168,18 +178,21 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) vmime::shared_ptr msg = vmime::make_shared (); - VASSERT_THROW("Connection", tr->send(msg, exp, recips), - vmime::net::smtp::SMTPMessageSizeExceedsMaxLimitsException); + VASSERT_THROW( + "Max size limit exception", + tr->send(msg, exp, recips), + vmime::net::smtp::SMTPMessageSizeExceedsMaxLimitsException + ); } - void testSMTPUTF8_available() - { + void testSMTPUTF8_available() { + // Test with UTF8 sender { vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); @@ -213,8 +226,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) { vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); @@ -240,14 +253,14 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) } } - void testSMTPUTF8_notAvailable() - { + void testSMTPUTF8_notAvailable() { + // Test with UTF8 sender { vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); @@ -281,8 +294,8 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) { vmime::shared_ptr session = vmime::net::session::create(); - vmime::shared_ptr tr = session->getTransport - (vmime::utility::url("smtp://localhost")); + vmime::shared_ptr tr = + session->getTransport(vmime::utility::url("smtp://localhost")); tr->setSocketFactory(vmime::make_shared > >()); tr->setTimeoutHandlerFactory(vmime::make_shared ()); @@ -309,4 +322,3 @@ VMIME_TEST_SUITE_BEGIN(SMTPTransportTest) } VMIME_TEST_SUITE_END - diff --git a/tests/net/smtp/SMTPTransportTestUtils.hpp b/tests/net/smtp/SMTPTransportTestUtils.hpp index b5af2f10..8710639f 100644 --- a/tests/net/smtp/SMTPTransportTestUtils.hpp +++ b/tests/net/smtp/SMTPTransportTestUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -24,20 +24,21 @@ /** Accepts connection and fails on greeting. */ -class greetingErrorSMTPTestSocket : public lineBasedTestSocket -{ +class greetingErrorSMTPTestSocket : public lineBasedTestSocket { + public: - void onConnected() - { + void onConnected() { + localSend("421 test.vmime.org Service not available, closing transmission channel\r\n"); disconnect(); } - void processCommand() - { - if (!haveMoreLines()) + void processCommand() { + + if (!haveMoreLines()) { return; + } getNextLine(); @@ -52,12 +53,12 @@ public: * Test send(). * Ensure MAIL and RCPT commands are sent correctly. */ -class MAILandRCPTSMTPTestSocket : public lineBasedTestSocket -{ +class MAILandRCPTSMTPTestSocket : public lineBasedTestSocket { + public: - MAILandRCPTSMTPTestSocket() - { + MAILandRCPTSMTPTestSocket() { + m_recipients.insert("recipient1@test.vmime.org"); m_recipients.insert("recipient2@test.vmime.org"); m_recipients.insert("recipient3@test.vmime.org"); @@ -66,60 +67,61 @@ public: m_ehloSent = m_heloSent = m_mailSent = m_rcptSent = m_dataSent = m_quitSent = false; } - ~MAILandRCPTSMTPTestSocket() - { + ~MAILandRCPTSMTPTestSocket() { + VASSERT("Client must send the DATA command", m_dataSent); VASSERT("Client must send the QUIT command", m_quitSent); } - void onConnected() - { + void onConnected() { + localSend("220 test.vmime.org Service ready\r\n"); processCommand(); m_state = STATE_COMMAND; } - void processCommand() - { - if (!haveMoreLines()) + void processCommand() { + + if (!haveMoreLines()) { return; + } vmime::string line = getNextLine(); std::istringstream iss(line); - switch (m_state) - { + switch (m_state) { + case STATE_NOT_CONNECTED: localSend("451 Requested action aborted: invalid state\r\n"); break; - case STATE_COMMAND: - { + case STATE_COMMAND: { + std::string cmd; iss >> cmd; - if (cmd.empty()) - { + if (cmd.empty()) { + localSend("500 Syntax error, command unrecognized\r\n"); - } - else if (cmd == "EHLO") - { + + } else if (cmd == "EHLO") { + localSend("502 Command not implemented\r\n"); m_ehloSent = true; - } - else if (cmd == "HELO") - { + + } else if (cmd == "HELO") { + VASSERT("Client must send the EHLO command before HELO", m_ehloSent); localSend("250 OK\r\n"); m_heloSent = true; - } - else if (cmd == "MAIL") - { + + } else if (cmd == "MAIL") { + VASSERT("Client must send the HELO command", m_heloSent); VASSERT("The MAIL command must be sent only one time", !m_mailSent); @@ -128,9 +130,9 @@ public: localSend("250 OK\r\n"); m_mailSent = true; - } - else if (cmd == "RCPT") - { + + } else if (cmd == "RCPT") { + const vmime::size_t lt = line.find('<'); const vmime::size_t gt = line.find('>'); @@ -138,23 +140,25 @@ public: VASSERT("RCPT >", gt != vmime::string::npos); VASSERT("RCPT ><", gt >= lt); - const vmime::string recip = vmime::string - (line.begin() + lt + 1, line.begin() + gt); + const vmime::string recip = + vmime::string(line.begin() + lt + 1, line.begin() + gt); std::set ::iterator it = m_recipients.find(recip); - VASSERT(std::string("Recipient not found: '") + recip + "'", - it != m_recipients.end()); + VASSERT( + std::string("Recipient not found: '") + recip + "'", + it != m_recipients.end() + ); m_recipients.erase(it); localSend("250 OK, recipient accepted\r\n"); m_rcptSent = true; - } - else if (cmd == "DATA") - { + + } else if (cmd == "DATA") { + VASSERT("Client must send the MAIL command", m_mailSent); VASSERT("Client must send the RCPT command", m_rcptSent); VASSERT("All recipients", m_recipients.empty()); @@ -165,35 +169,35 @@ public: m_msgData.clear(); m_dataSent = true; - } - else if (cmd == "NOOP") - { + + } else if (cmd == "NOOP") { + localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { + + } else if (cmd == "QUIT") { + m_quitSent = true; localSend("221 test.vmime.org Service closing transmission channel\r\n"); - } - else - { + + } else { + localSend("502 Command not implemented\r\n"); } break; } - case STATE_DATA: - { - if (line == ".") - { + case STATE_DATA: { + + if (line == ".") { + VASSERT_EQ("Data", "Message data\r\n", m_msgData); localSend("250 Message accepted for delivery\r\n"); m_state = STATE_COMMAND; - } - else - { + + } else { + m_msgData += line + "\r\n"; } @@ -207,8 +211,7 @@ public: private: - enum State - { + enum State { STATE_NOT_CONNECTED, STATE_COMMAND, STATE_DATA @@ -230,45 +233,45 @@ private: * * Test CHUNKING extension/BDAT command. */ -class chunkingSMTPTestSocket : public testSocket -{ +class chunkingSMTPTestSocket : public testSocket { + public: - chunkingSMTPTestSocket() - { + chunkingSMTPTestSocket() { + m_state = STATE_NOT_CONNECTED; m_bdatChunkCount = 0; m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false; } - ~chunkingSMTPTestSocket() - { + ~chunkingSMTPTestSocket() { + VASSERT_EQ("BDAT chunk count", 3, m_bdatChunkCount); VASSERT("Client must send the QUIT command", m_quitSent); } - void onConnected() - { + void onConnected() { + localSend("220 test.vmime.org Service ready\r\n"); processCommand(); m_state = STATE_COMMAND; } - void onDataReceived() - { - if (m_state == STATE_DATA) - { - if (m_bdatChunkReceived != m_bdatChunkSize) - { + void onDataReceived() { + + if (m_state == STATE_DATA) { + + if (m_bdatChunkReceived != m_bdatChunkSize) { + const size_t remaining = m_bdatChunkSize - m_bdatChunkReceived; const size_t received = localReceiveRaw(NULL, remaining); m_bdatChunkReceived += received; } - if (m_bdatChunkReceived == m_bdatChunkSize) - { + if (m_bdatChunkReceived == m_bdatChunkSize) { + m_state = STATE_COMMAND; } } @@ -276,58 +279,59 @@ public: processCommand(); } - void processCommand() - { + void processCommand() { + vmime::string line; - if (!localReceiveLine(line)) + if (!localReceiveLine(line)) { return; + } std::istringstream iss(line); - switch (m_state) - { + switch (m_state) { + case STATE_NOT_CONNECTED: localSend("451 Requested action aborted: invalid state\r\n"); break; - case STATE_COMMAND: - { + case STATE_COMMAND: { + std::string cmd; iss >> cmd; - if (cmd == "EHLO") - { + if (cmd == "EHLO") { + localSend("250-test.vmime.org says hello\r\n"); localSend("250 CHUNKING\r\n"); m_ehloSent = true; - } - else if (cmd == "HELO") - { + + } else if (cmd == "HELO") { + VASSERT("Client must not send the HELO command, as EHLO succeeded", false); - } - else if (cmd == "MAIL") - { + + } else if (cmd == "MAIL") { + VASSERT("The MAIL command must be sent only one time", !m_mailSent); localSend("250 OK\r\n"); m_mailSent = true; - } - else if (cmd == "RCPT") - { + + } else if (cmd == "RCPT") { + localSend("250 OK, recipient accepted\r\n"); m_rcptSent = true; - } - else if (cmd == "DATA") - { + + } else if (cmd == "DATA") { + VASSERT("BDAT must be used here!", false); - } - else if (cmd == "BDAT") - { + + } else if (cmd == "BDAT") { + VASSERT("Client must send the MAIL command", m_mailSent); VASSERT("Client must send the RCPT command", m_rcptSent); @@ -337,23 +341,23 @@ public: std::string last; iss >> last; - if (m_bdatChunkCount == 0) - { + if (m_bdatChunkCount == 0) { + VASSERT_EQ("BDAT chunk1 size", 262144, chunkSize); VASSERT_EQ("BDAT chunk1 last", "", last); - } - else if (m_bdatChunkCount == 1) - { + + } else if (m_bdatChunkCount == 1) { + VASSERT_EQ("BDAT chunk2 size", 262144, chunkSize); VASSERT_EQ("BDAT chunk2 last", "", last); - } - else if (m_bdatChunkCount == 2) - { + + } else if (m_bdatChunkCount == 2) { + VASSERT_EQ("BDAT chunk3 size", 4712, chunkSize); VASSERT_EQ("BDAT chunk3 last", "LAST", last); - } - else - { + + } else { + VASSERT("No more BDAT command should be issued!", false); } @@ -363,19 +367,19 @@ public: m_state = STATE_DATA; localSend("250 chunk received\r\n"); - } - else if (cmd == "NOOP") - { + + } else if (cmd == "NOOP") { + localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { + + } else if (cmd == "QUIT") { + localSend("221 test.vmime.org Service closing transmission channel\r\n"); m_quitSent = true; - } - else - { + + } else { + localSend("502 Command not implemented\r\n"); } @@ -389,8 +393,7 @@ public: private: - enum State - { + enum State { STATE_NOT_CONNECTED, STATE_COMMAND, STATE_DATA @@ -404,22 +407,21 @@ private: }; -class SMTPTestMessage : public vmime::message -{ +class SMTPTestMessage : public vmime::message { + public: - vmime::size_t getChunkBufferSize() const - { + vmime::size_t getChunkBufferSize() const { + static vmime::net::smtp::SMTPChunkingOutputStreamAdapter chunkStream(vmime::null, 0, NULL); return chunkStream.getBlockSize(); } - const std::vector & getChunks() const - { + const std::vector & getChunks() const { + static std::vector chunks; - if (chunks.size() == 0) - { + if (chunks.size() == 0) { chunks.push_back(vmime::string(1000, 'A')); chunks.push_back(vmime::string(3000, 'B')); chunks.push_back(vmime::string(500000, 'C')); @@ -429,12 +431,15 @@ public: return chunks; } - void generateImpl - (const vmime::generationContext& /* ctx */, vmime::utility::outputStream& outputStream, - const size_t /* curLinePos */ = 0, size_t* /* newLinePos */ = NULL) const - { - for (size_t i = 0, n = getChunks().size() ; i < n ; ++i) - { + void generateImpl( + const vmime::generationContext& /* ctx */, + vmime::utility::outputStream& outputStream, + const size_t /* curLinePos */ = 0, + size_t* /* newLinePos */ = NULL + ) const { + + for (size_t i = 0, n = getChunks().size() ; i < n ; ++i) { + const vmime::string& chunk = getChunks()[i]; outputStream.write(chunk.data(), chunk.size()); } @@ -448,72 +453,74 @@ public: * Test SIZE extension. */ template -class bigMessageSMTPTestSocket : public testSocket -{ +class bigMessageSMTPTestSocket : public testSocket { + public: - bigMessageSMTPTestSocket() - { + bigMessageSMTPTestSocket() { + m_state = STATE_NOT_CONNECTED; m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false; } - ~bigMessageSMTPTestSocket() - { + ~bigMessageSMTPTestSocket() { + VASSERT("Client must send the QUIT command", m_quitSent); } - void onConnected() - { + void onConnected() { + localSend("220 test.vmime.org Service ready\r\n"); processCommand(); m_state = STATE_COMMAND; } - void onDataReceived() - { + void onDataReceived() { + processCommand(); } - void processCommand() - { + void processCommand() { + vmime::string line; - if (!localReceiveLine(line)) + if (!localReceiveLine(line)) { return; + } std::istringstream iss(line); - switch (m_state) - { + switch (m_state) { + case STATE_NOT_CONNECTED: localSend("451 Requested action aborted: invalid state\r\n"); break; - case STATE_COMMAND: - { + case STATE_COMMAND: { + std::string cmd; iss >> cmd; - if (cmd == "EHLO") - { + if (cmd == "EHLO") { + localSend("250-test.vmime.org says hello\r\n"); - if (WITH_CHUNKING) + if (WITH_CHUNKING) { localSend("250-CHUNKING\r\n"); + } localSend("250 SIZE 1000000\r\n"); m_ehloSent = true; - } - else if (cmd == "HELO") - { + + } else if (cmd == "HELO") { + VASSERT("Client must not send the HELO command, as EHLO succeeded", false); - } - else if (cmd == "MAIL") - { + + } else if (cmd == "MAIL") { + VASSERT("The MAIL command must be sent only one time", !m_mailSent); std::string address; @@ -529,19 +536,19 @@ public: localSend("552 Channel size limit exceeded\r\n"); m_mailSent = true; - } - else if (cmd == "NOOP") - { + + } else if (cmd == "NOOP") { + localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { + + } else if (cmd == "QUIT") { + localSend("221 test.vmime.org Service closing transmission channel\r\n"); m_quitSent = true; - } - else - { + + } else { + VASSERT("No other command should be sent", false); localSend("502 Command not implemented\r\n"); @@ -557,8 +564,7 @@ public: private: - enum State - { + enum State { STATE_NOT_CONNECTED, STATE_COMMAND, STATE_DATA @@ -571,22 +577,25 @@ private: template -class SMTPBigTestMessage : public vmime::message -{ +class SMTPBigTestMessage : public vmime::message { + public: - size_t getGeneratedSize(const vmime::generationContext& /* ctx */) - { + size_t getGeneratedSize(const vmime::generationContext& /* ctx */) { + return SIZE; } - void generateImpl(const vmime::generationContext& /* ctx */, - vmime::utility::outputStream& outputStream, - const vmime::size_t /* curLinePos */ = 0, - vmime::size_t* /* newLinePos */ = NULL) const - { - for (unsigned int i = 0, n = SIZE ; i < n ; ++i) + void generateImpl( + const vmime::generationContext& /* ctx */, + vmime::utility::outputStream& outputStream, + const vmime::size_t /* curLinePos */ = 0, + vmime::size_t* /* newLinePos */ = NULL + ) const { + + for (unsigned int i = 0, n = SIZE ; i < n ; ++i) { outputStream.write("X", 1); + } } }; @@ -597,20 +606,20 @@ typedef SMTPBigTestMessage <4194304> SMTPBigTestMessage4MB; /** SMTP test server for SMTPUTF8 extension. */ template -class UTF8SMTPTestSocket : public lineBasedTestSocket -{ +class UTF8SMTPTestSocket : public lineBasedTestSocket { + public: - UTF8SMTPTestSocket() - { - if (SUPPORTS_UTF8) - { + UTF8SMTPTestSocket() { + + if (SUPPORTS_UTF8) { + m_rcptLines.insert("RCPT TO:"); m_rcptLines.insert("RCPT TO:"); m_rcptLines.insert("RCPT TO:"); - } - else - { + + } else { + m_rcptLines.insert("RCPT TO:"); m_rcptLines.insert("RCPT TO:"); m_rcptLines.insert("RCPT TO:<=?utf-8?Q?r=C3=A9cepteur?=@test.vmime.org>"); @@ -620,75 +629,76 @@ public: m_ehloSent = m_mailSent = m_rcptSent = m_dataSent = m_quitSent = false; } - ~UTF8SMTPTestSocket() - { + ~UTF8SMTPTestSocket() { + } - void onConnected() - { + void onConnected() { + localSend("220 test.vmime.org Service ready\r\n"); processCommand(); m_state = STATE_COMMAND; } - void processCommand() - { - if (!haveMoreLines()) + void processCommand() { + + if (!haveMoreLines()) { return; + } vmime::string line = getNextLine(); std::istringstream iss(line); - switch (m_state) - { + switch (m_state) { + case STATE_NOT_CONNECTED: localSend("451 Requested action aborted: invalid state\r\n"); break; - case STATE_COMMAND: - { + case STATE_COMMAND: { + std::string cmd; iss >> cmd; - if (cmd.empty()) - { + if (cmd.empty()) { + localSend("500 Syntax error, command unrecognized\r\n"); - } - else if (cmd == "EHLO") - { - if (SUPPORTS_UTF8) - { + + } else if (cmd == "EHLO") { + + if (SUPPORTS_UTF8) { + localSend("250-test.vmime.org\r\n"); localSend("250 SMTPUTF8\r\n"); - } - else - { + + } else { + localSend("250 test.vmime.org\r\n"); } m_ehloSent = true; - } - else if (cmd == "HELO") - { + + } else if (cmd == "HELO") { + VASSERT("Client must not send the HELO command, as EHLO succeeded", false); - } - else if (cmd == "MAIL") - { + + } else if (cmd == "MAIL") { + VASSERT("Client must send the EHLO command", m_ehloSent); VASSERT("The MAIL command must be sent only one time", !m_mailSent); - if (SUPPORTS_UTF8) - { + if (SUPPORTS_UTF8) { + VASSERT( "MAIL", std::string("MAIL FROM: SMTPUTF8") == line || std::string("MAIL FROM: SMTPUTF8") == line ); - } - else - { + + } else { + VASSERT( "MAIL", std::string("MAIL FROM:") == line @@ -699,9 +709,9 @@ public: localSend("250 OK\r\n"); m_mailSent = true; - } - else if (cmd == "RCPT") - { + + } else if (cmd == "RCPT") { + std::set ::iterator it = m_rcptLines.find(line); VASSERT(std::string("RCPT not found: '") + line + "'", it != m_rcptLines.end()); @@ -711,9 +721,9 @@ public: localSend("250 OK, recipient accepted\r\n"); m_rcptSent = true; - } - else if (cmd == "DATA") - { + + } else if (cmd == "DATA") { + VASSERT("Client must send the MAIL command", m_mailSent); VASSERT("Client must send the RCPT command", m_rcptSent); VASSERT("All recipients", m_rcptLines.empty()); @@ -724,35 +734,35 @@ public: m_msgData.clear(); m_dataSent = true; - } - else if (cmd == "NOOP") - { + + } else if (cmd == "NOOP") { + localSend("250 Completed\r\n"); - } - else if (cmd == "QUIT") - { + + } else if (cmd == "QUIT") { + m_quitSent = true; localSend("221 test.vmime.org Service closing transmission channel\r\n"); - } - else - { + + } else { + localSend("502 Command not implemented\r\n"); } break; } - case STATE_DATA: - { - if (line == ".") - { + case STATE_DATA: { + + if (line == ".") { + VASSERT_EQ("Data", "Message data\r\n", m_msgData); localSend("250 Message accepted for delivery\r\n"); m_state = STATE_COMMAND; - } - else - { + + } else { + m_msgData += line + "\r\n"; } @@ -766,8 +776,7 @@ public: private: - enum State - { + enum State { STATE_NOT_CONNECTED, STATE_COMMAND, STATE_DATA diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp index 6bd3b7db..866f8de4 100644 --- a/tests/parser/attachmentHelperTest.cpp +++ b/tests/parser/attachmentHelperTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -39,23 +39,25 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VMIME_TEST_LIST_END - static const vmime::string getStructure(const vmime::shared_ptr & part) - { + static const vmime::string getStructure(const vmime::shared_ptr & part) { + vmime::shared_ptr bdy = part->getBody(); vmime::string res = part->getBody()->getContentType().generate(); - if (bdy->getPartCount() == 0) + if (bdy->getPartCount() == 0) { return res; + } res += "["; - for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) - { + for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) { + vmime::shared_ptr subPart = bdy->getPartAt(i); - if (i != 0) + if (i != 0) { res += ","; + } res += getStructure(subPart); } @@ -63,8 +65,10 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) return res + "]"; } - static const vmime::string extractBodyContents(const vmime::shared_ptr & part) - { + static const vmime::string extractBodyContents( + const vmime::shared_ptr & part + ) { + vmime::shared_ptr cth = part->getBody()->getContents(); vmime::string data; @@ -75,8 +79,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) return data; } - void testAddAttachment1() - { + void testAddAttachment1() { + vmime::string data = "Content-Type: text/plain\r\n" "\r\n" @@ -86,9 +90,11 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) vmime::shared_ptr msg = vmime::make_shared (); msg->parse(data); - vmime::shared_ptr att = vmime::make_shared - (vmime::make_shared ("test"), - vmime::mediaType("image/jpeg")); + vmime::shared_ptr att = + vmime::make_shared ( + vmime::make_shared ("test"), + vmime::mediaType("image/jpeg") + ); vmime::attachmentHelper::addAttachment(msg, att); @@ -96,8 +102,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VASSERT_EQ("2", "The text\r\n", extractBodyContents(msg->getBody()->getPartAt(0))); } - void testAddAttachment2() - { + void testAddAttachment2() { + vmime::string data = "Content-Type: multipart/mixed; boundary=\"foo\"\r\n" "\r\n" @@ -115,9 +121,11 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) vmime::shared_ptr msg = vmime::make_shared (); msg->parse(data); - vmime::shared_ptr att = vmime::make_shared - (vmime::make_shared ("test"), - vmime::mediaType("image/jpeg")); + vmime::shared_ptr att = + vmime::make_shared ( + vmime::make_shared ("test"), + vmime::mediaType("image/jpeg") + ); vmime::attachmentHelper::addAttachment(msg, att); @@ -128,8 +136,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) } // Initial part is encoded - void testAddAttachment3() - { + void testAddAttachment3() { + vmime::string data = "Content-Type: text/plain\r\n" "Content-Transfer-Encoding: base64\r\n" @@ -139,9 +147,11 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) vmime::shared_ptr msg = vmime::make_shared (); msg->parse(data); - vmime::shared_ptr att = vmime::make_shared - (vmime::make_shared ("test"), - vmime::mediaType("image/jpeg")); + vmime::shared_ptr att = + vmime::make_shared ( + vmime::make_shared ("test"), + vmime::mediaType("image/jpeg") + ); vmime::attachmentHelper::addAttachment(msg, att); @@ -151,8 +161,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) // Content-Disposition: attachment // No other field - void testIsBodyPartAnAttachment1() - { + void testIsBodyPartAnAttachment1() { + vmime::string data = "Content-Disposition: attachment\r\n\r\nFoo\r\n"; vmime::shared_ptr p = vmime::make_shared (); @@ -163,8 +173,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) // No Content-Disposition field // Content-Type: multipart/* or text/* - void testIsBodyPartAnAttachment2() - { + void testIsBodyPartAnAttachment2() { + vmime::string data = "Content-Type: multipart/*\r\n\r\nFoo\r\n"; vmime::shared_ptr p = vmime::make_shared (); @@ -180,8 +190,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) } // No Content-Disposition field - void testIsBodyPartAnAttachment3() - { + void testIsBodyPartAnAttachment3() { + vmime::string data = "Content-Type: application/octet-stream\r\n\r\nFoo\r\n"; vmime::shared_ptr p = vmime::make_shared (); @@ -192,8 +202,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) // Content-Disposition: attachment // Content-Id field present - void testIsBodyPartAnAttachment4() - { + void testIsBodyPartAnAttachment4() { + vmime::string data = "Content-Disposition: attachment\r\n" "Content-Type: application/octet-stream\r\n" "Content-Id: bar\r\n" @@ -205,8 +215,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VASSERT_EQ("1", false, vmime::attachmentHelper::isBodyPartAnAttachment(p)); } - void testGetBodyPartAttachment() - { + void testGetBodyPartAttachment() { + vmime::string data = "Content-Type: image/jpeg\r\n" "Content-Description: foobar\r\n" @@ -238,8 +248,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VASSERT_EQ("7", part->getHeader()->generate(), att->getHeader()->generate()); } - void testAddAttachmentMessage1() - { + void testAddAttachmentMessage1() { + const vmime::string data = "Subject: Test message\r\n" "Content-Type: text/plain\r\n" @@ -282,8 +292,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VASSERT_EQ("4", "Attached message body", extractBodyContents(amsgOut)); } - void testGetBodyPartAttachmentMessage() - { + void testGetBodyPartAttachmentMessage() { + const vmime::string data = "Subject: Test message\r\n" "Content-Type: multipart/mixed; boundary=\"foo\"\r\n" @@ -305,8 +315,8 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) VASSERT_EQ("0", 2, msg->getBody()->getPartCount()); - vmime::shared_ptr att = vmime::attachmentHelper:: - getBodyPartAttachment(msg->getBody()->getPartAt(0)); + vmime::shared_ptr att = + vmime::attachmentHelper::getBodyPartAttachment(msg->getBody()->getPartAt(0)); VASSERT("1", att != NULL); @@ -323,4 +333,3 @@ VMIME_TEST_SUITE_BEGIN(attachmentHelperTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp index e6ff737a..91742553 100644 --- a/tests/parser/bodyPartTest.cpp +++ b/tests/parser/bodyPartTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,15 +42,21 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VMIME_TEST_LIST_END - static const vmime::string extractComponentString - (const vmime::string& buffer, const vmime::component& c) - { - return vmime::string(buffer.begin() + c.getParsedOffset(), - buffer.begin() + c.getParsedOffset() + c.getParsedLength()); + static const vmime::string extractComponentString( + const vmime::string& buffer, + const vmime::component& c + ) { + + return vmime::string( + buffer.begin() + c.getParsedOffset(), + buffer.begin() + c.getParsedOffset() + c.getParsedLength() + ); } - static const vmime::string extractContents(const vmime::shared_ptr & cts) - { + static const vmime::string extractContents( + const vmime::shared_ptr & cts + ) { + std::ostringstream oss; vmime::utility::outputStreamAdapter os(oss); @@ -60,8 +66,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) } - void testParse() - { + void testParse() { + vmime::string str1 = "HEADER\r\n\r\nBODY"; vmime::bodyPart p1; p1.parse(str1); @@ -84,8 +90,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("6", "BODY", extractComponentString(str3, *p3.getBody())); } - void testParseMissingLastBoundary() - { + void testParseMissingLastBoundary() { + vmime::string str = "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\"" "\r\n\r\n" @@ -101,8 +107,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("part2-body", "BODY2", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents())); } - void testGenerate() - { + void testGenerate() { + vmime::bodyPart p1; p1.getHeader()->getField("Foo")->setValue(vmime::string("bar")); p1.getBody()->setContents(vmime::make_shared ("Baz")); @@ -110,8 +116,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("1", "Foo: bar\r\n\r\nBaz", p1.generate()); } - void testPrologEpilog() - { + void testPrologEpilog() { + const char testMail[] = "To: test@vmime.org\r\n" "From: test@vmime.org\r\n" @@ -136,8 +142,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) // Test for bug fix: prolog should not be encoded // http://sourceforge.net/tracker/?func=detail&atid=525568&aid=3174903&group_id=69724 - void testPrologEncoding() - { + void testPrologEncoding() { + const char testmail[] = "To: test@vmime.org\r\n" "From: test@vmime.org\r\n" @@ -169,8 +175,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) std::string ostr; vmime::utility::outputStreamStringAdapter out(ostr); - for (int i = 0 ; i < 10 ; ++i) - { + for (int i = 0 ; i < 10 ; ++i) { + ostr.clear(); msg->parse(istr); @@ -184,8 +190,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("epilog", "Epilog text", msg->getBody()->getEpilogText()); } - void testSuccessiveBoundaries() - { + void testSuccessiveBoundaries() { + vmime::string str = "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\"" "\r\n\r\n" @@ -202,8 +208,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("part2-body", "", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents())); } - void testTransportPaddingInBoundary() - { + void testTransportPaddingInBoundary() { + vmime::string str = "Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\"" "\r\n\r\n" @@ -221,8 +227,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) } /** Ensure '7bit' encoding is used when body is 7-bit only. */ - void testGenerate7bit() - { + void testGenerate7bit() { + vmime::shared_ptr p1 = vmime::make_shared (); p1->setText(vmime::make_shared ("Part1 is US-ASCII only.")); @@ -233,8 +239,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("1", "7bit", header1->ContentTransferEncoding()->getValue()->generate()); } - void testTextUsageForQPEncoding() - { + void testTextUsageForQPEncoding() { + vmime::shared_ptr part = vmime::make_shared (); part->setText(vmime::make_shared ("Part1-line1\r\nPart1-line2\r\n\x89")); @@ -255,8 +261,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("2", "Part1-line1\r\nPart1-line2\r\n=89", oss.str()); } - void testParseGuessBoundary() - { + void testParseGuessBoundary() { + // Boundary is not specified in "Content-Type" field // Parser will try to guess it from message contents. @@ -276,8 +282,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("part2-body", "BODY2", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents())); } - void testParseGuessBoundaryWithTransportPadding() - { + void testParseGuessBoundaryWithTransportPadding() { + // Boundary is not specified in "Content-Type" field // Parser will try to guess it from message contents. // Transport padding white spaces should be ignored. @@ -298,8 +304,8 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) VASSERT_EQ("part2-body", "BODY2", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents())); } - void testParseVeryBigMessage() - { + void testParseVeryBigMessage() { + // When parsing from a seekable input stream, body contents should not // be kept in memory in a "stringContentHandler" object. Instead, content // should be accessible via a "streamContentHandler" object. @@ -323,8 +329,9 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) oss << BODY1_BEGIN; - for (unsigned int i = 0 ; i < BODY1_REPEAT ; ++i) + for (unsigned int i = 0 ; i < BODY1_REPEAT ; ++i) { oss << BODY1_LINE; + } oss << BODY1_END; @@ -333,8 +340,9 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) << "HEADER2\r\n" << "\r\n"; - for (unsigned int i = 0 ; i < BODY2_REPEAT ; ++i) + for (unsigned int i = 0 ; i < BODY2_REPEAT ; ++i) { oss << BODY2_LINE; + } oss << "\r\n" << "--MY-BOUNDARY--\r\n"; @@ -366,4 +374,3 @@ VMIME_TEST_SUITE_BEGIN(bodyPartTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/bodyTest.cpp b/tests/parser/bodyTest.cpp index 92a4575e..fa396af5 100644 --- a/tests/parser/bodyTest.cpp +++ b/tests/parser/bodyTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,35 +32,49 @@ VMIME_TEST_SUITE_BEGIN(bodyTest) VMIME_TEST_LIST_END - void testGenerate_Text() - { + void testGenerate_Text() { + // RFC-2015: [Quoted-Printable encoding] A line break in a text body, // represented as a CRLF sequence in the text canonical form, must be // represented by a line break which is also a CRLF sequence, in the // Quoted-Printable encoding vmime::bodyPart p; - p.getBody()->setContents(vmime::make_shared - ("Foo éé\r\né bar\r\nbaz"), vmime::mediaType("text", "plain"), - vmime::charset("utf-8"), vmime::encoding("quoted-printable")); + p.getBody()->setContents( + vmime::make_shared ( + "Foo éé\r\né bar\r\nbaz" + ), + vmime::mediaType("text", "plain"), + vmime::charset("utf-8"), + vmime::encoding("quoted-printable") + ); - VASSERT_EQ("generate", + VASSERT_EQ( + "generate", "Foo =C3=A9=C3=A9\r\n" "=C3=A9 bar\r\n" "baz", - p.getBody()->generate()); + p.getBody()->generate() + ); } - void testGenerate_NonText() - { - vmime::bodyPart p; - p.getBody()->setContents(vmime::make_shared - ("Binary\xfa\xfb\r\ndata\r\n\r\n\xfc"), vmime::mediaType("application", "octet-stream"), - vmime::charset("utf-8"), vmime::encoding("quoted-printable")); + void testGenerate_NonText() { - VASSERT_EQ("generate", + vmime::bodyPart p; + p.getBody()->setContents( + vmime::make_shared ( + "Binary\xfa\xfb\r\ndata\r\n\r\n\xfc" + ), + vmime::mediaType("application", "octet-stream"), + vmime::charset("utf-8"), + vmime::encoding("quoted-printable") + ); + + VASSERT_EQ( + "generate", "Binary=FA=FB=0D=0Adata=0D=0A=0D=0A=FC", - p.getBody()->generate()); + p.getBody()->generate() + ); } VMIME_TEST_SUITE_END diff --git a/tests/parser/charsetFilteredOutputStreamTest.cpp b/tests/parser/charsetFilteredOutputStreamTest.cpp index 9b8397a8..0ebd83a7 100644 --- a/tests/parser/charsetFilteredOutputStreamTest.cpp +++ b/tests/parser/charsetFilteredOutputStreamTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,8 +40,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) VMIME_TEST_LIST_END - void testInputBufferUnderflow() - { + void testInputBufferUnderflow() { + vmime::shared_ptr cc = vmime::charsetConverter::create("utf-8", "iso-8859-1"); @@ -65,8 +65,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) VASSERT_EQ("chunk 2", toHex("f\xf8o"), toHex(output)); } - void testInvalidInput1() - { + void testInvalidInput1() { + vmime::string in("foo\xab\xcd\xef bar"); vmime::string expectedOut("foo??? bar"); @@ -74,9 +74,7 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) vmime::utility::outputStreamStringAdapter osa(actualOut); vmime::shared_ptr conv = - vmime::charsetConverter::create - (vmime::charset("utf-8"), - vmime::charset("iso-8859-1")); + vmime::charsetConverter::create(vmime::charset("utf-8"), vmime::charset("iso-8859-1")); vmime::shared_ptr os = conv->getFilteredOutputStream(osa); @@ -96,10 +94,10 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) } // Using 'bufferedStreamCopy' - void testStreamCopy() - { - for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) - { + void testStreamCopy() { + + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; std::ostringstream testName; @@ -133,10 +131,10 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) } // One byte at a time - void testOneByteAtTime() - { - for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) - { + void testOneByteAtTime() { + + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; std::ostringstream testName; @@ -173,10 +171,10 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest) } // Variable chunks - void testVariableInputChunk() - { - for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) - { + void testVariableInputChunk() { + + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; std::ostringstream testName; diff --git a/tests/parser/charsetTest.cpp b/tests/parser/charsetTest.cpp index e599c5b5..e44bef5b 100644 --- a/tests/parser/charsetTest.cpp +++ b/tests/parser/charsetTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,10 +52,10 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VMIME_TEST_LIST_END - void testConvertStringValid() - { - for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) - { + void testConvertStringValid() { + + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; std::ostringstream testName; @@ -76,10 +76,10 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) } } - void testConvertStreamValid() - { - for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) - { + void testConvertStreamValid() { + + for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i) { + const charsetTestSuiteStruct& entry = charsetTestSuites[i]; std::ostringstream testName; @@ -96,8 +96,7 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) vmime::utility::inputStreamStringAdapter is(in); - vmime::charset::convert - (is, os, entry.fromCharset, entry.toCharset); + vmime::charset::convert(is, os, entry.fromCharset, entry.toCharset); os.flush(); @@ -105,8 +104,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) } } - void testEncodingHebrew1255() - { + void testEncodingHebrew1255() { + // hewbrew string in windows-1255 charset const char data[] = "\xe9\xf9\xf7\xf8\xe9\xf9\xf8\xf7\xe9\xe9\xf9"; vmime::word w = vmime::word(data, "windows-1255"); @@ -115,11 +114,14 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VASSERT_EQ("1", "=?windows-1255?B?6fn3+On5+Pfp6fk=?=", encoded); } - static const vmime::string convertHelper - (const vmime::string& in, const vmime::charset& csrc, const vmime::charset& cdest, - const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions(), - vmime::charsetConverter::status* st = NULL) - { + static const vmime::string convertHelper( + const vmime::string& in, + const vmime::charset& csrc, + const vmime::charset& cdest, + const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions(), + vmime::charsetConverter::status* st = NULL + ) { + vmime::shared_ptr conv = vmime::charsetConverter::create(csrc, cdest, opts); @@ -129,8 +131,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) return out; } - void testEncodeIDNA() - { + void testEncodeIDNA() { + VASSERT_EQ("1", "xn--espaol-zwa", convertHelper("español", "utf-8", "idna")); // Tests from ICANN @@ -141,8 +143,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VASSERT_EQ("3.2", "xn--kgbechtv", convertHelper("إختبار", "utf-8", "idna")); } - void testDecodeIDNA() - { + void testDecodeIDNA() { + VASSERT_EQ("1", "español", convertHelper("xn--espaol-zwa", "idna", "utf-8")); // Tests from ICANN @@ -153,21 +155,23 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VASSERT_EQ("3.2", "إختبار", convertHelper("xn--kgbechtv", "idna", "utf-8")); } - void testUTF7Support() - { + void testUTF7Support() { + // Ensure UTF-7 is supported, because it is used for IMAP VASSERT_EQ("1", "VMime +- UTF-7 encoding", convertHelper("VMime + UTF-7 encoding", "utf-8", "utf-7")); VASSERT_EQ("2", "f+APg-o", convertHelper("\x66\xc3\xb8\x6f", "utf-8", "utf-7")); } - void testReplaceInvalidSequence() - { + void testReplaceInvalidSequence() { + vmime::charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = true; opts.invalidSequence = "?"; - vmime::string res = convertHelper - ("\x61\xf1\x80\x80\xe1\x80\xc2\x62\x80\x63\x80\xbf\x64", "utf-8", "iso-8859-1", opts); + vmime::string res = convertHelper( + "\x61\xf1\x80\x80\xe1\x80\xc2\x62\x80\x63\x80\xbf\x64", + "utf-8", "iso-8859-1", opts + ); // Result should be in the form "a???b?c??d" or "a??????b?c??d"... // Remove consecutive question marks for easier matching. @@ -180,8 +184,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) ); } - void testStopOnInvalidSequence() - { + void testStopOnInvalidSequence() { + vmime::charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = false; @@ -192,8 +196,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) ); } - void testStatus() - { + void testStatus() { + vmime::charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = false; @@ -206,23 +210,22 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VASSERT_EQ("outputBytesWritten", 7, st.outputBytesWritten); } - void testStatusWithInvalidSequence() - { + void testStatusWithInvalidSequence() { + vmime::charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = false; vmime::charsetConverter::status st; - try - { + try { + // 01234 5 6789 0 1 convertHelper("Fran\xc3\xa7ois\xf1\x80\x65", "utf-8", "iso-8859-1", opts, &st); - } - catch (vmime::exceptions::illegal_byte_sequence_for_charset& e) - { - } - catch (...) - { + + } catch (vmime::exceptions::illegal_byte_sequence_for_charset& e) { + + } catch (...) { + throw; } @@ -230,8 +233,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) VASSERT_EQ("outputBytesWritten", 8, st.outputBytesWritten); } - void testIsValidText() - { + void testIsValidText() { + // Invalid text const vmime::string invalidText("Fran\xc3\xa7ois\xf1\x80\x65"); vmime::string::size_type firstInvalidByte; @@ -247,4 +250,3 @@ VMIME_TEST_SUITE_BEGIN(charsetTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/charsetTestSuites.hpp b/tests/parser/charsetTestSuites.hpp index cb10e29e..9653016b 100644 --- a/tests/parser/charsetTestSuites.hpp +++ b/tests/parser/charsetTestSuites.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -22,8 +22,8 @@ // -struct charsetTestSuiteStruct -{ +struct charsetTestSuiteStruct { + const char* fromCharset; const char* toCharset; const char* fromBytes; @@ -33,8 +33,8 @@ struct charsetTestSuiteStruct }; -static const charsetTestSuiteStruct charsetTestSuites[] = -{ +static const charsetTestSuiteStruct charsetTestSuites[] = { + // Test data 1 (excerpt from http://www.gnu.org) { "gb2312", "utf-8", @@ -97,7 +97,6 @@ static const charsetTestSuiteStruct charsetTestSuites[] = "\xe7\xbb\x9f\x20\xe3\x80\x82\x0a", 0 } - }; static const vmime::size_t charsetTestSuitesCount = sizeof(charsetTestSuites) / sizeof(charsetTestSuites[0]); diff --git a/tests/parser/datetimeTest.cpp b/tests/parser/datetimeTest.cpp index 90bbebbb..61c85221 100644 --- a/tests/parser/datetimeTest.cpp +++ b/tests/parser/datetimeTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,10 +33,9 @@ VMIME_TEST_SUITE_BEGIN(datetimeTest) VMIME_TEST_LIST_END - void testParse() - { - struct datetimePair - { + void testParse() { + + struct datetimePair { vmime::string parseBuffer; vmime::datetime result; }; @@ -45,8 +44,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeTest) // so we test some cases. Don't forget to add a new test case // each time you encounter a bug in date/time parsing (after // you have fixed it). - datetimePair pairs[] = - { + datetimePair pairs[] = { + { /* 1 */ "Mon, 8 Nov 2004 13:42:56 +0000 (GMT)", vmime::datetime(2004, 11, 8, 13, 42, 56, vmime::datetime::GMT) }, @@ -66,8 +65,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeTest) vmime::datetime(2004, 11, 18, 21, 44, 54, vmime::datetime::GMT3) } }; - for (unsigned int i = 0 ; i < sizeof(pairs) / sizeof(pairs[0]) ; ++i) - { + for (unsigned int i = 0 ; i < sizeof(pairs) / sizeof(pairs[0]) ; ++i) { + vmime::datetime d; d.parse(pairs[i].parseBuffer); @@ -78,15 +77,15 @@ VMIME_TEST_SUITE_BEGIN(datetimeTest) } } - void testGenerate() - { + void testGenerate() { + vmime::datetime d1(2005, 7, 8, 4, 5, 6, 1 * 60 + 23); VASSERT_EQ("1", "Fri, 8 Jul 2005 04:05:06 +0123", d1.generate()); } - void testCompare() - { + void testCompare() { + // Date1 = Date2 vmime::datetime d1(2005, 4, 22, 14, 6, 0, vmime::datetime::GMT2); vmime::datetime d2(2005, 4, 22, 10, 6, 0, vmime::datetime::GMT_2); @@ -122,4 +121,3 @@ VMIME_TEST_SUITE_BEGIN(datetimeTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/dispositionTest.cpp b/tests/parser/dispositionTest.cpp index 7b767caa..f51c51e8 100644 --- a/tests/parser/dispositionTest.cpp +++ b/tests/parser/dispositionTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,8 +33,8 @@ VMIME_TEST_SUITE_BEGIN(dispositionTest) VMIME_TEST_LIST_END - void testParse() - { + void testParse() { + // disposition-mode ";" disposition-type // [ "/" disposition-modifier *( "," disposition-modifier ) ] // @@ -84,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(dispositionTest) VASSERT_EQ("5.6", "modif2", disp5.getModifierList()[1]); } - void testGenerate() - { + void testGenerate() { + vmime::disposition disp; VASSERT_EQ("1", "automatic-action/MDN-sent-automatically;displayed", disp.generate()); @@ -112,8 +112,8 @@ VMIME_TEST_SUITE_BEGIN(dispositionTest) VASSERT_EQ("6", "amode/smode;type/modif1,modif2", disp.generate()); } - void testModifiers() - { + void testModifiers() { + vmime::disposition disp1; VASSERT_EQ("1", false, disp1.hasModifier("foo")); @@ -148,4 +148,3 @@ VMIME_TEST_SUITE_BEGIN(dispositionTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/emailAddressTest.cpp b/tests/parser/emailAddressTest.cpp index 2de401a9..f2a70705 100644 --- a/tests/parser/emailAddressTest.cpp +++ b/tests/parser/emailAddressTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,29 +45,26 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VMIME_TEST_LIST_END - void setUp() - { + 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } } - void tearDown() - { + void tearDown() { + // Restore default locale std::locale::global(std::locale("C")); } - void testParseASCII() - { + void testParseASCII() { + vmime::emailAddress eml1("local@domain"); VASSERT_EQ("1/local", "local", eml1.getLocalName()); VASSERT_EQ("1/domain", "domain", eml1.getDomainName()); @@ -78,8 +75,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("2/domain", vmime::platform::getHandler()->getHostName(), eml2.getDomainName()); } - void testParseEAI() - { + void testParseEAI() { + // Examples taken from Wikipedia (http://en.wikipedia.org/wiki/Email_address) // Latin Alphabet (with diacritics): @@ -103,8 +100,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("4/domain", "ящик-с-апельсинами.рф", eml4.getDomainName()); } - void testParseInvalid() - { + void testParseInvalid() { + // Only one @ is allowed outside quotation marks vmime::emailAddress eml1("local@part@domain"); VASSERT_EQ("1/local", "local", eml1.getLocalName()); @@ -132,8 +129,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("5/domain", vmime::platform::getHandler()->getHostName(), eml5.getDomainName()); } - void testParseSpecialChars() - { + void testParseSpecialChars() { + // Examples taken from Wikipedia (http://en.wikipedia.org/wiki/Email_address) vmime::emailAddress eml1("\" \"@example.org"); @@ -161,8 +158,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("6/domain", "strange.example.com", eml6.getDomainName()); } - void testParseCommentInLocalPart() - { + void testParseCommentInLocalPart() { + vmime::emailAddress eml1("john.smith(comment)@example.com"); VASSERT_EQ("1/local", "john.smith", eml1.getLocalName()); VASSERT_EQ("1/domain", "example.com", eml1.getDomainName()); @@ -180,8 +177,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("4/domain", "example.com", eml4.getDomainName()); } - void testParseCommentInDomainPart() - { + void testParseCommentInDomainPart() { + vmime::emailAddress eml1("john.smith@(comment)example.com"); VASSERT_EQ("1/local", "john.smith", eml1.getLocalName()); VASSERT_EQ("1/domain", "example.com", eml1.getDomainName()); @@ -199,8 +196,8 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("4/domain", "example.com", eml4.getDomainName()); } - void testParseRFC2047EncodedLocalPart() - { + void testParseRFC2047EncodedLocalPart() { + vmime::emailAddress eml1("=?utf-8?Q?Pel=C3=A9?=@example.com"); VASSERT_EQ("1/local", "Pelé", eml1.getLocalName()); VASSERT_EQ("1/domain", "example.com", eml1.getDomainName()); @@ -214,47 +211,71 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VASSERT_EQ("3/domain", "黒川.com", eml3.getDomainName()); } - void testGenerateASCII() - { - VASSERT_EQ("email 1", "local@domain", vmime::emailAddress("local", "domain").generate()); + void testGenerateASCII() { - VASSERT_EQ("email 2", "=?utf-8?Q?Pel=C3=A9?=@example.com", - vmime::emailAddress("Pelé", "example.com").generate()); - VASSERT_EQ("email 3", "=?utf-8?B?55Sy5paQ?=@xn--5rtw95l.xn--wgv71a", - vmime::emailAddress("甲斐", "黒川.日本").generate()); - VASSERT_EQ("email 4", "mailtest@xn--r8jz45g.xn--zckzah", - vmime::emailAddress("mailtest", "例え.テスト").generate()); - VASSERT_EQ("email 5", "mailtest@xn--mgbh0fb.xn--kgbechtv", - vmime::emailAddress("mailtest", "مثال.إختبار").generate()); + VASSERT_EQ( + "email 1", "local@domain", + vmime::emailAddress("local", "domain").generate() + ); + VASSERT_EQ( + "email 2", "=?utf-8?Q?Pel=C3=A9?=@example.com", + vmime::emailAddress("Pelé", "example.com").generate() + ); + VASSERT_EQ( + "email 3", "=?utf-8?B?55Sy5paQ?=@xn--5rtw95l.xn--wgv71a", + vmime::emailAddress("甲斐", "黒川.日本").generate() + ); + VASSERT_EQ( + "email 4", "mailtest@xn--r8jz45g.xn--zckzah", + vmime::emailAddress("mailtest", "例え.テスト").generate() + ); + VASSERT_EQ( + "email 5", "mailtest@xn--mgbh0fb.xn--kgbechtv", + vmime::emailAddress("mailtest", "مثال.إختبار").generate() + ); } - void testGenerateEAI() - { + void testGenerateEAI() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(true); vmime::generationContext::switcher contextSwitcher(ctx); - VASSERT_EQ("email 1", "Pelé@example.com", - vmime::emailAddress("Pelé", "example.com").generate()); - VASSERT_EQ("email 2", "δοκιμή@παράδειγμα.δοκιμή", - vmime::emailAddress("δοκιμή", "παράδειγμα.δοκιμή").generate()); - VASSERT_EQ("email 3", "甲斐@黒川.日本", - vmime::emailAddress("甲斐", "黒川.日本").generate()); - VASSERT_EQ("email 4", "чебурашка@ящик-с-апельсинами.рф", - vmime::emailAddress("чебурашка", "ящик-с-апельсинами.рф").generate()); + VASSERT_EQ( + "email 1", "Pelé@example.com", + vmime::emailAddress("Pelé", "example.com").generate() + ); + VASSERT_EQ( + "email 2", "δοκιμή@παράδειγμα.δοκιμή", + vmime::emailAddress("δοκιμή", "παράδειγμα.δοκιμή").generate() + ); + VASSERT_EQ( + "email 3", "甲斐@黒川.日本", + vmime::emailAddress("甲斐", "黒川.日本").generate() + ); + VASSERT_EQ( + "email 4", "чебурашка@ящик-с-апельсинами.рф", + vmime::emailAddress("чебурашка", "ящик-с-апельсинами.рф").generate() + ); } - void testGenerateSpecialChars() - { - VASSERT_EQ("email 1", "\"very.unusual.@.unusual.com\"@example.com", - vmime::emailAddress("very.unusual.@.unusual.com", "example.com").generate()); + void testGenerateSpecialChars() { - VASSERT_EQ("email 2", "\"very.(),:;<>[]\\\".VERY.\\\"very@\\\\ \\\"very\\\".unusual\"@strange.example.com", - vmime::emailAddress("very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual", "strange.example.com").generate()); + VASSERT_EQ( + "email 1", "\"very.unusual.@.unusual.com\"@example.com", + vmime::emailAddress("very.unusual.@.unusual.com", "example.com").generate() + ); - VASSERT_EQ("email 3", "\" \"@example.com", - vmime::emailAddress(" ", "example.com").generate()); + VASSERT_EQ( + "email 2", "\"very.(),:;<>[]\\\".VERY.\\\"very@\\\\ \\\"very\\\".unusual\"@strange.example.com", + vmime::emailAddress("very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual", "strange.example.com").generate() + ); + + VASSERT_EQ( + "email 3", "\" \"@example.com", + vmime::emailAddress(" ", "example.com").generate() + ); } VMIME_TEST_SUITE_END diff --git a/tests/parser/emptyContentHandlerTest.cpp b/tests/parser/emptyContentHandlerTest.cpp index 81e2ed6b..43cd8c2b 100644 --- a/tests/parser/emptyContentHandlerTest.cpp +++ b/tests/parser/emptyContentHandlerTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,30 +38,30 @@ VMIME_TEST_SUITE_BEGIN(emptyContentHandlerTest) VMIME_TEST_LIST_END - void testIsEmpty() - { + void testIsEmpty() { + vmime::emptyContentHandler cth; VASSERT_TRUE("empty", cth.isEmpty()); } - void testGetLength() - { + void testGetLength() { + vmime::emptyContentHandler cth; VASSERT_EQ("length", 0, cth.getLength()); } - void testIsEncoded() - { + void testIsEncoded() { + vmime::emptyContentHandler cth; VASSERT_FALSE("encoded", cth.isEncoded()); VASSERT_EQ("encoding", vmime::contentHandler::NO_ENCODING, cth.getEncoding()); } - void testExtract() - { + void testExtract() { + vmime::emptyContentHandler cth; std::ostringstream oss; @@ -72,8 +72,8 @@ VMIME_TEST_SUITE_BEGIN(emptyContentHandlerTest) VASSERT_EQ("extract", "", oss.str()); } - void testExtractRaw() - { + void testExtractRaw() { + vmime::emptyContentHandler cth; std::ostringstream oss; @@ -84,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(emptyContentHandlerTest) VASSERT_EQ("extractRaw", "", oss.str()); } - void testGenerate() - { + void testGenerate() { + vmime::emptyContentHandler cth; std::ostringstream oss; diff --git a/tests/parser/fileContentHandlerTest.cpp b/tests/parser/fileContentHandlerTest.cpp index 9d1459db..e979b52f 100644 --- a/tests/parser/fileContentHandlerTest.cpp +++ b/tests/parser/fileContentHandlerTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,8 +42,8 @@ VMIME_TEST_SUITE_BEGIN(fileContentHandlerTest) vmime::string testDataEncoded, testDataDecoded; - void setUp() - { + void setUp() { + testDataDecoded = "ABCDEFGHIJKLMNOPQRSTUVWXYZ \x12\x34\x56\x78\x90 abcdefghijklmnopqrstuvwxyz0123456789"; testDataEncoded = "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogEjRWeJAgYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5"; @@ -58,38 +58,38 @@ VMIME_TEST_SUITE_BEGIN(fileContentHandlerTest) testFile->getFileWriter()->getOutputStream()->write(testDataEncoded.data(), testDataEncoded.length()); } - void tearDown() - { + void tearDown() { + testFile->remove(); testFile = vmime::null; } - void testIsEmpty() - { + void testIsEmpty() { + vmime::fileContentHandler cth; VASSERT_TRUE("empty", cth.isEmpty()); } - void testGetLength() - { + void testGetLength() { + vmime::fileContentHandler cth(testFile); VASSERT_FALSE("empty", cth.isEmpty()); VASSERT_EQ("length", testDataEncoded.length(), cth.getLength()); } - void testIsEncoded() - { + void testIsEncoded() { + vmime::fileContentHandler cth(testFile, vmime::encoding("base64")); VASSERT_TRUE("encoded", cth.isEncoded()); VASSERT_EQ("encoding", "base64", cth.getEncoding().generate()); } - void testExtract() - { + void testExtract() { + vmime::fileContentHandler cth(testFile, vmime::encoding("base64")); std::ostringstream oss; @@ -101,8 +101,8 @@ VMIME_TEST_SUITE_BEGIN(fileContentHandlerTest) VASSERT_EQ("extract", testDataDecoded, oss.str()); } - void testExtractRaw() - { + void testExtractRaw() { + vmime::fileContentHandler cth(testFile, vmime::encoding("base64")); std::ostringstream oss; @@ -114,8 +114,8 @@ VMIME_TEST_SUITE_BEGIN(fileContentHandlerTest) VASSERT_EQ("extractRaw", testDataEncoded, oss.str()); } - void testGenerate() - { + void testGenerate() { + vmime::fileContentHandler cth(testFile, vmime::encoding("base64")); std::ostringstream oss; @@ -124,8 +124,11 @@ VMIME_TEST_SUITE_BEGIN(fileContentHandlerTest) cth.generate(osa, vmime::encoding("quoted-printable")); // Data should be reencoded from B64 to QP - VASSERT_EQ("generate", - "ABCDEFGHIJKLMNOPQRSTUVWXYZ =124Vx=90 abcdefghijklmnopqrstuvwxyz0123456789", oss.str()); + VASSERT_EQ( + "generate", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ =124Vx=90 abcdefghijklmnopqrstuvwxyz0123456789", + oss.str() + ); } VMIME_TEST_SUITE_END diff --git a/tests/parser/headerFieldTest.cpp b/tests/parser/headerFieldTest.cpp index 0642dae7..78d04800 100644 --- a/tests/parser/headerFieldTest.cpp +++ b/tests/parser/headerFieldTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,27 +34,35 @@ VMIME_TEST_SUITE_BEGIN(headerFieldTest) VMIME_TEST_LIST_END - void testBadValueType() - { + void testBadValueType() { + vmime::shared_ptr hfactory = vmime::headerFieldFactory::getInstance(); // "To" header field accepts values of type "addressList" vmime::shared_ptr to = hfactory->create(vmime::fields::TO); - VASSERT_THROW("to", + + VASSERT_THROW( + "to", to->setValue(vmime::mailbox("email@vmime.org")), - vmime::exceptions::bad_field_value_type); + vmime::exceptions::bad_field_value_type + ); // Unregistered header field accepts any value type vmime::shared_ptr custom = hfactory->create("X-MyCustomHeader"); - VASSERT_NO_THROW("custom/1", - custom->setValue(vmime::mailbox("email@vmime.org"))); - VASSERT_NO_THROW("custom/2", - custom->setValue(vmime::text("field value text"))); + + VASSERT_NO_THROW( + "custom/1", + custom->setValue(vmime::mailbox("email@vmime.org")) + ); + VASSERT_NO_THROW( + "custom/2", + custom->setValue(vmime::text("field value text")) + ); } - void testValueOnNextLine() - { + void testValueOnNextLine() { + vmime::parsingContext ctx; const vmime::string buffer = "Field: \r\n\tfield data"; @@ -69,8 +77,8 @@ VMIME_TEST_SUITE_BEGIN(headerFieldTest) VASSERT_EQ("Field value", "field data", hvalue->getWholeBuffer()); } - void testStripSpacesAtEnd() - { + void testStripSpacesAtEnd() { + vmime::parsingContext ctx; const vmime::string buffer = "Field: \r\n\tfield data "; @@ -85,8 +93,8 @@ VMIME_TEST_SUITE_BEGIN(headerFieldTest) VASSERT_EQ("Field value", toHex("field data"), toHex(hvalue->getWholeBuffer())); } - void testValueWithEmptyLine() - { + void testValueWithEmptyLine() { + vmime::parsingContext ctx; const vmime::string buffer = "Field: \r\n\tdata1\r\n\tdata2\r\n\t\r\n\tdata3"; diff --git a/tests/parser/headerTest.cpp b/tests/parser/headerTest.cpp index 959fc631..839acee5 100644 --- a/tests/parser/headerTest.cpp +++ b/tests/parser/headerTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -64,18 +64,18 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VMIME_TEST_LIST_END - static const std::string getFieldValue(const vmime::headerField& field) - { + static const std::string getFieldValue(const vmime::headerField& field) { + std::ostringstream oss; vmime::utility::outputStreamAdapter voss(oss); field.generate(voss); - return (oss.str()); + return oss.str(); } // has function tests - void testHas1() - { + void testHas1() { + vmime::header hdr; hdr.parse("From: x\r\nTo: y\r\nTo: z\r\n"); @@ -84,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Value", false, res); } - void testHas2() - { + void testHas2() { + vmime::header hdr; hdr.parse("X: x\r\nTo: y\r\nTo: z\r\n"); @@ -95,8 +95,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // appendField function tests - void testAppend1() - { + void testAppend1() { + vmime::header hdr; hdr.parse(""); @@ -109,8 +109,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0])); } - void testAppend2() - { + void testAppend2() { + vmime::header hdr; hdr.parse("A: a\r\n"); @@ -125,8 +125,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // insertFieldBefore - void testInsertFieldBefore1() - { + void testInsertFieldBefore1() { + vmime::header hdr; hdr.parse("A: a\r\nC: c\r\n"); @@ -141,8 +141,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2])); } - void testInsertFieldBefore2() - { + void testInsertFieldBefore2() { + vmime::header hdr; hdr.parse("A: a\r\nC: c\r\n"); @@ -158,8 +158,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // insertFieldAfter - void testInsertFieldAfter1() - { + void testInsertFieldAfter1() { + vmime::header hdr; hdr.parse("A: a\r\nC: c\r\n"); @@ -174,8 +174,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2])); } - void testInsertFieldAfter2() - { + void testInsertFieldAfter2() { + vmime::header hdr; hdr.parse("A: a\r\nC: c\r\n"); @@ -191,8 +191,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // replaceField - void testReplaceField() - { + void testReplaceField() { + vmime::header hdr; hdr.parse("A: a\r\nB: b\r\nC: c\r\n"); @@ -208,8 +208,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // removeField - void testRemoveField1() - { + void testRemoveField1() { + vmime::header hdr1, hdr2; hdr1.parse("A: a\r\nB: b\r\nC: c\r\n"); hdr2.parse("A: a\r\nB: b\r\nC: c\r\n"); @@ -230,8 +230,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Second value", "C: c", headerTest::getFieldValue(*res2[1])); } - void testRemoveField2() - { + void testRemoveField2() { + vmime::header hdr1, hdr2; hdr1.parse("A: a\r\n"); hdr2.parse("A: a\r\n"); @@ -247,8 +247,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // removeAllFields - void testRemoveAllFields() - { + void testRemoveAllFields() { + vmime::header hdr1, hdr2; hdr1.parse("A: a\r\n"); hdr2.parse("A: a\r\nB: b\r\n"); @@ -264,8 +264,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // getFieldCount - void testgetFieldCount() - { + void testgetFieldCount() { + vmime::header hdr; hdr.parse("A: a\r\nB: b\r\nC: c\r\nD: d\r\n"); @@ -273,16 +273,16 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // isEmpty - void testIsEmpty1() - { + void testIsEmpty1() { + vmime::header hdr; hdr.parse("A: a\r\nB: b\r\nC: c\r\n"); VASSERT_EQ("Value", false, hdr.isEmpty()); } - void testIsEmpty2() - { + void testIsEmpty2() { + vmime::header hdr; hdr.parse("\r\n"); @@ -290,8 +290,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // getFieldAt - void testGetFieldAt() - { + void testGetFieldAt() { + vmime::header hdr; hdr.parse("B: b\r\nA: a\r\nC: c\r\n"); @@ -301,8 +301,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // getFieldList - void testGetFieldList1() - { + void testGetFieldList1() { + vmime::header hdr; hdr.parse("A: a\r\nB: b1\r\nC: c\r\nB: b2\r\n"); @@ -315,8 +315,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Thourth value", "B: b2", headerTest::getFieldValue(*res[3])); } - void testGetFieldList2() - { + void testGetFieldList2() { + vmime::header hdr; hdr.parse("\r\n"); @@ -326,8 +326,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // find function tests - void testFind1() - { + void testFind1() { + vmime::header hdr; hdr.parse("A: a\r\nB: b\r\nC: c\r\nB: d\r\n"); @@ -337,8 +337,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } // getAllByName function tests - void testFindAllFields1() - { + void testFindAllFields1() { + vmime::header hdr; hdr.parse("A: a1\nC: c1\n"); @@ -347,8 +347,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Count", static_cast (0), res.size()); } - void testFindAllFields2() - { + void testFindAllFields2() { + vmime::header hdr; hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\n"); @@ -359,8 +359,8 @@ VMIME_TEST_SUITE_BEGIN(headerTest) VASSERT_EQ("Second value", "B: b2", headerTest::getFieldValue(*res[1])); } - void testFindAllFields3() - { + void testFindAllFields3() { + vmime::header hdr; hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\nC: c3\nC: c2\n"); @@ -373,4 +373,3 @@ VMIME_TEST_SUITE_BEGIN(headerTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/htmlTextPartTest.cpp b/tests/parser/htmlTextPartTest.cpp index 9eef5e84..6dfaaa0b 100644 --- a/tests/parser/htmlTextPartTest.cpp +++ b/tests/parser/htmlTextPartTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,9 +34,10 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) VMIME_TEST_LIST_END - static const vmime::string extractContent - (const vmime::shared_ptr & cth) - { + static const vmime::string extractContent( + const vmime::shared_ptr & cth + ) { + std::ostringstream oss; vmime::utility::outputStreamAdapter osa(oss); @@ -46,8 +47,8 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) } - void testParseText() - { + void testParseText() { + const vmime::string msgString = "" "MIME-Version: 1.0\r\n" "Content-Type: multipart/alternative; boundary=\"LEVEL1\"\r\n" @@ -94,8 +95,8 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) /** Test parsing of embedded objects by CID (Content-Id). */ - void testParseEmbeddedObjectsCID() - { + void testParseEmbeddedObjectsCID() { + const vmime::string msgString = "" "MIME-Version: 1.0\r\n" "Content-Type: multipart/alternative; boundary=\"LEVEL1\"\r\n" @@ -137,8 +138,10 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) VASSERT_EQ("part-count2", 3, msg->getBody()->getPartAt(1)->getBody()->getPartCount()); vmime::htmlTextPart htmlPart; - htmlPart.parse(msg, msg->getBody()->getPartAt(1), - msg->getBody()->getPartAt(1)->getBody()->getPartAt(1)); + htmlPart.parse( + msg, msg->getBody()->getPartAt(1), + msg->getBody()->getPartAt(1)->getBody()->getPartAt(1) + ); // Two embedded objects should be found. // BUGFIX: "CID:" prefix is not case-sensitive. @@ -172,8 +175,8 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) /** Test parsing of embedded objects by location. */ - void testParseEmbeddedObjectsLocation() - { + void testParseEmbeddedObjectsLocation() { + const vmime::string msgString = "" "MIME-Version: 1.0\r\n" "Content-Type: multipart/alternative; boundary=\"LEVEL1\"\r\n" @@ -209,8 +212,10 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) VASSERT_EQ("part-count2", 2, msg->getBody()->getPartAt(1)->getBody()->getPartCount()); vmime::htmlTextPart htmlPart; - htmlPart.parse(msg, msg->getBody()->getPartAt(1), - msg->getBody()->getPartAt(1)->getBody()->getPartAt(1)); + htmlPart.parse( + msg, msg->getBody()->getPartAt(1), + msg->getBody()->getPartAt(1)->getBody()->getPartAt(1) + ); // Only one embedded object VASSERT_EQ("count", 1, htmlPart.getObjectCount()); @@ -234,4 +239,3 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) // TODO: test generation of text parts VMIME_TEST_SUITE_END - diff --git a/tests/parser/mailboxGroupTest.cpp b/tests/parser/mailboxGroupTest.cpp index 6c1319da..11a7f08f 100644 --- a/tests/parser/mailboxGroupTest.cpp +++ b/tests/parser/mailboxGroupTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,8 +34,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxGroupTest) VMIME_TEST_LIST_END - void testParseExtraWhitespaces() - { + void testParseExtraWhitespaces() { + vmime::mailboxGroup mgrp; mgrp.parse(" \t group : aaa , bbb "); @@ -49,8 +49,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxGroupTest) VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName()); } - void testParseNoEndDelimiter() - { + void testParseNoEndDelimiter() { + vmime::addressList addrs; addrs.parse("group: aaa , bbb "); @@ -70,8 +70,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxGroupTest) VASSERT_EQ("mbox2.name", "bbb", mgrp->getMailboxAt(1)->getName()); } - void testParseExtraChars() - { + void testParseExtraChars() { + vmime::mailboxGroup mgrp; mgrp.parse("group: aaa , bbb ; extra chars here..."); @@ -85,8 +85,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxGroupTest) VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName()); } - void testEmptyGroup() - { + void testEmptyGroup() { + vmime::mailboxGroup mgrp; mgrp.parse("Undisclosed recipients:;"); diff --git a/tests/parser/mailboxListTest.cpp b/tests/parser/mailboxListTest.cpp index c921069e..7505acd9 100644 --- a/tests/parser/mailboxListTest.cpp +++ b/tests/parser/mailboxListTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,8 +32,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxListTest) // Disposition-Notification-To:: - void testParseGroup() - { + void testParseGroup() { + // Groups should be extracted to multiple mailboxes in mailbox lists vmime::mailboxList mboxList; mboxList.parse("email1@domain1.com, : , email3@domain3.com"); @@ -45,4 +45,3 @@ VMIME_TEST_SUITE_BEGIN(mailboxListTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp index 92fcd98f..127bb422 100644 --- a/tests/parser/mailboxTest.cpp +++ b/tests/parser/mailboxTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -34,10 +34,10 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) VMIME_TEST_LIST_END - void testParse() - { - static const vmime::string testSuitesParse[] = - { + void testParse() { + + static const vmime::string testSuitesParse[] = { + // Test 1 "My (this is a comment)name ", @@ -94,8 +94,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]" }; - for (unsigned int i = 0 ; i < sizeof(testSuitesParse) / sizeof(testSuitesParse[0]) / 2 ; ++i) - { + for (unsigned int i = 0 ; i < sizeof(testSuitesParse) / sizeof(testSuitesParse[0]) / 2 ; ++i) { + vmime::string in = testSuitesParse[i * 2]; vmime::string out = testSuitesParse[i * 2 + 1]; @@ -112,8 +112,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) } } - void testEmptyEmailAddress() - { + void testEmptyEmailAddress() { + vmime::addressList addrList; addrList.parse("\"Full Name\" <>"); @@ -127,8 +127,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) VASSERT_EQ("email", "", mbox->getEmail()); } - void testSeparatorInComment() - { + void testSeparatorInComment() { + vmime::addressList addrList; addrList.parse("aaa(comment,comment)@vmime.org, bbb@vmime.org"); @@ -146,8 +146,8 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) VASSERT_EQ("email2", "bbb@vmime.org", mbox2->getEmail()); } - void testAddressInName() - { + void testAddressInName() { + vmime::mailbox mbox; mbox.parse("a@b.c "); @@ -156,4 +156,3 @@ VMIME_TEST_SUITE_BEGIN(mailboxTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/mediaTypeTest.cpp b/tests/parser/mediaTypeTest.cpp index 4002b714..e98cfcda 100644 --- a/tests/parser/mediaTypeTest.cpp +++ b/tests/parser/mediaTypeTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VMIME_TEST_LIST_END - void testConstructors() - { + void testConstructors() { + vmime::mediaType t1; VASSERT_EQ("1.1", vmime::mediaTypes::APPLICATION, t1.getType()); @@ -53,8 +53,8 @@ VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VASSERT_EQ("3.2", "sub", t3.getSubType()); } - void testCopy() - { + void testCopy() { + vmime::mediaType t1("type/sub"); VASSERT_EQ("eq1", "type", t1.getType()); @@ -72,8 +72,8 @@ VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VASSERT("copyFrom", t1 == t2); } - void testSetFromString() - { + void testSetFromString() { + vmime::mediaType t1; t1.setFromString("type/sub"); @@ -81,8 +81,8 @@ VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VASSERT_EQ("1.2", "sub", t1.getSubType()); } - void testParse() - { + void testParse() { + vmime::mediaType t1; t1.parse("type/sub"); @@ -90,12 +90,11 @@ VMIME_TEST_SUITE_BEGIN(mediaTypeTest) VASSERT_EQ("1.2", "sub", t1.getSubType()); } - void testGenerate() - { + void testGenerate() { + vmime::mediaType t1("type", "sub"); VASSERT_EQ("1", "type/sub", t1.generate()); } VMIME_TEST_SUITE_END - diff --git a/tests/parser/messageIdSequenceTest.cpp b/tests/parser/messageIdSequenceTest.cpp index bc5c7617..0237108d 100644 --- a/tests/parser/messageIdSequenceTest.cpp +++ b/tests/parser/messageIdSequenceTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -32,8 +32,8 @@ VMIME_TEST_SUITE_BEGIN(messageIdSequenceTest) VMIME_TEST_LIST_END - void testParse() - { + void testParse() { + vmime::messageIdSequence s1; s1.parse(""); @@ -61,8 +61,8 @@ VMIME_TEST_SUITE_BEGIN(messageIdSequenceTest) VASSERT_EQ("4.5", "d", s4.getMessageIdAt(1)->getRight()); } - void testGenerate() - { + void testGenerate() { + vmime::messageIdSequence s1; s1.appendMessageId(vmime::make_shared ("a", "b")); @@ -76,4 +76,3 @@ VMIME_TEST_SUITE_BEGIN(messageIdSequenceTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/messageIdTest.cpp b/tests/parser/messageIdTest.cpp index 9863ae51..84330939 100644 --- a/tests/parser/messageIdTest.cpp +++ b/tests/parser/messageIdTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,8 +33,8 @@ VMIME_TEST_SUITE_BEGIN(messageIdTest) VMIME_TEST_LIST_END - void testParse() - { + void testParse() { + vmime::messageId m1; m1.parse(""); @@ -42,8 +42,8 @@ VMIME_TEST_SUITE_BEGIN(messageIdTest) VASSERT_EQ("1.2", "b", m1.getRight()); } - void testParseInvalid() - { + void testParseInvalid() { + vmime::messageId m1; m1.parse("foo@bar"); @@ -51,8 +51,8 @@ VMIME_TEST_SUITE_BEGIN(messageIdTest) VASSERT_EQ("1.2", "bar", m1.getRight()); } - void testGenerate() - { + void testGenerate() { + vmime::messageId m1; VASSERT_EQ("1", "<>", m1.generate()); @@ -75,4 +75,3 @@ VMIME_TEST_SUITE_BEGIN(messageIdTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/messageTest.cpp b/tests/parser/messageTest.cpp index 3891b47e..b89d63e5 100644 --- a/tests/parser/messageTest.cpp +++ b/tests/parser/messageTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -31,16 +31,24 @@ VMIME_TEST_SUITE_BEGIN(messageTest) VMIME_TEST_LIST_END - void testGetGeneratedSize() - { + void testGetGeneratedSize() { + vmime::generationContext ctx; vmime::shared_ptr msg = vmime::make_shared (); msg->getHeader()->getField("Foo")->setValue(vmime::string("bar")); vmime::htmlTextPart textPart; - textPart.setPlainText(vmime::make_shared ("Foo bar bazé foo foo foo")); - textPart.setText(vmime::make_shared ("Foo bar bazé foo foo foo")); + textPart.setPlainText( + vmime::make_shared ( + "Foo bar bazé foo foo foo" + ) + ); + textPart.setText( + vmime::make_shared ( + "Foo bar bazé foo foo foo" + ) + ); textPart.generateIn(msg, msg); // Estimated/computed generated size must be greater than the actual generated size @@ -54,4 +62,3 @@ VMIME_TEST_SUITE_BEGIN(messageTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/parameterTest.cpp b/tests/parser/parameterTest.cpp index 0cf2099f..464c3059 100644 --- a/tests/parser/parameterTest.cpp +++ b/tests/parser/parameterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,12 +45,12 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) // HACK: parameterizedHeaderField constructor is private - class parameterizedHeaderField : public vmime::parameterizedHeaderField - { + class parameterizedHeaderField : public vmime::parameterizedHeaderField { + public: - parameterizedHeaderField() - { + parameterizedHeaderField() { + setName("F"); setValue(vmime::headerFieldFactory::getInstance()->createValue(getName())); setValue(vmime::word("X")); @@ -58,15 +58,17 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) using vmime::parameterizedHeaderField::generate; - const vmime::string generate - (const vmime::generationContext::EncodedParameterValueModes genMode, - const vmime::size_t maxLineLength = 0) const - { + const vmime::string generate( + const vmime::generationContext::EncodedParameterValueModes genMode, + const vmime::size_t maxLineLength = 0 + ) const { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setEncodedParameterValueMode(genMode); - if (maxLineLength != 0) + if (maxLineLength != 0) { ctx.setMaxLineLength(maxLineLength); + } std::ostringstream oss; vmime::utility::outputStreamAdapter adapter(oss); @@ -78,15 +80,17 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) }; - const vmime::string generateParameter - (const vmime::parameter& param, - const vmime::generationContext& ctx, - const vmime::size_t maxLineLength = 0) const - { + const vmime::string generateParameter( + const vmime::parameter& param, + const vmime::generationContext& ctx, + const vmime::size_t maxLineLength = 0 + ) const { + vmime::generationContext ctx2(ctx); - if (maxLineLength != 0) + if (maxLineLength != 0) { ctx2.setMaxLineLength(maxLineLength); + } std::ostringstream oss; vmime::utility::outputStreamAdapter adapter(oss); @@ -108,29 +112,26 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) (p.getParameterAt(n)->getValue().getBuffer()) - void setUp() - { + 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } } - void tearDown() - { + void tearDown() { + // Restore default locale std::locale::global(std::locale("C")); } - void testParse() - { + void testParse() { + // Simple parameter parameterizedHeaderField p1; p1.parse("X; param1=value1;\r\n"); @@ -141,9 +142,11 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) // Multi-section parameters (1/2) parameterizedHeaderField p2a; - p2a.parse("X; param1=value1;\r\n" - " param2*0=\"val\";\r\n" - " param2*1=\"ue2\";"); + p2a.parse( + "X; param1=value1;\r\n" + " param2*0=\"val\";\r\n" + " param2*1=\"ue2\";" + ); VASSERT_EQ("2a.1", 2, p2a.getParameterCount()); VASSERT_EQ("2a.2", "param1", PARAM_NAME(p2a, 0)); @@ -153,10 +156,12 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) // Multi-section parameters (2/2) parameterizedHeaderField p2b; - p2b.parse("X; param1=value1;\r\n" - " param2=\"should be ignored\";\r\n" - " param2*0=\"val\";\r\n" - " param2*1=\"ue2\";"); + p2b.parse( + "X; param1=value1;\r\n" + " param2=\"should be ignored\";\r\n" + " param2*0=\"val\";\r\n" + " param2*1=\"ue2\";" + ); VASSERT_EQ("2b.1", 2, p2b.getParameterCount()); VASSERT_EQ("2b.2", "param1", PARAM_NAME(p2b, 0)); @@ -206,13 +211,15 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) VASSERT_EQ("7.3", "this is a slash: \"\\\"", PARAM_VALUE(p7, 0)); } - void testParseRFC2231() - { + void testParseRFC2231() { + // Extended parameter with charset specified in more than one // section (this is forbidden by RFC, but is should not fail) parameterizedHeaderField p1; - p1.parse("X; param1*0*=charset1'language1'value1;\r\n" - " param1*1*=charset2'language2'value2;"); + p1.parse( + "X; param1*0*=charset1'language1'value1;\r\n" + " param1*1*=charset2'language2'value2;" + ); VASSERT_EQ("1.1", 1, p1.getParameterCount()); VASSERT_EQ("1.2", "param1", PARAM_NAME(p1, 0)); @@ -222,8 +229,10 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) // Charset not specified in the first section (that is not encoded), // but specified in the second one (legal) parameterizedHeaderField p2; - p2.parse("X; param1*0=value1;\r\n" - " param1*1*=charset'language'value2;"); + p2.parse( + "X; param1*0=value1;\r\n" + " param1*1*=charset'language'value2;" + ); VASSERT_EQ("2.1", 1, p2.getParameterCount()); VASSERT_EQ("2.2", "param1", PARAM_NAME(p2, 0)); @@ -241,9 +250,11 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) // Multiple sections + charset specified and encoding parameterizedHeaderField p4; - p4.parse("X; param1*0*=charset'language'value1a%20;" - " param1*1*=value1b%20;" - " param1*2=value1c"); + p4.parse( + "X; param1*0*=charset'language'value1a%20;" + " param1*1*=value1b%20;" + " param1*2=value1c" + ); VASSERT_EQ("4.1", 1, p4.getParameterCount()); VASSERT_EQ("4.2", "param1", PARAM_NAME(p4, 0)); @@ -270,8 +281,8 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) VASSERT_EQ("6.5", "This is ***fun***", PARAM_BUFFER(p6, 0)); } - void testGenerate() - { + void testGenerate() { + // Simple parameter/value parameterizedHeaderField p1; p1.appendParameter(vmime::make_shared ("param1", "value1")); @@ -291,8 +302,8 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) VASSERT_EQ("2b", "F: X; param1=\"va\\\\lue\\\"1\"", p2b.generate()); } - void testGetGeneratedSize() - { + void testGetGeneratedSize() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); vmime::parameter p1("param1", "value1"); @@ -305,40 +316,70 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) VASSERT("1", p2b.getGeneratedSize(ctx) >= generateParameter(p2b, ctx).length()); } - void testGenerateRFC2231() - { + void testGenerateRFC2231() { + // Extended parameter with charset specifier parameterizedHeaderField p1; - p1.appendParameter(vmime::make_shared ("param1", - vmime::word("value 1\xe9", vmime::charset("charset")))); + p1.appendParameter( + vmime::make_shared ( + "param1", + vmime::word("value 1\xe9", vmime::charset("charset")) + ) + ); - VASSERT_EQ("1.no-encoding", "F: X; param1=\"value 1\"", - p1.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING)); + VASSERT_EQ( + "1.no-encoding", + "F: X; param1=\"value 1\"", + p1.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING) + ); - VASSERT_EQ("1.rfc2047", "F: X; param1=\"=?charset?Q?value_1=E9?=\"", - p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY)); + VASSERT_EQ( + "1.rfc2047", + "F: X; param1=\"=?charset?Q?value_1=E9?=\"", + p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY) + ); - VASSERT_EQ("1.rfc2231", "F: X; param1*=charset''value%201%E9", - p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY)); + VASSERT_EQ( + "1.rfc2231", + "F: X; param1*=charset''value%201%E9", + p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY) + ); - VASSERT_EQ("1.both", "F: X; param1=\"=?charset?Q?value_1=E9?=\";param1*=charset''value%201%E9", - p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047)); + VASSERT_EQ( + "1.both", + "F: X; param1=\"=?charset?Q?value_1=E9?=\";param1*=charset''value%201%E9", + p1.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) + ); // Value that spans on multiple lines parameterizedHeaderField p2; - p2.appendParameter(vmime::make_shared ("param1", - vmime::word("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", - vmime::charset("charset")))); + p2.appendParameter( + vmime::make_shared ( + "param1", + vmime::word( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", + vmime::charset("charset") + ) + ) + ); - VASSERT_EQ("2.no-encoding", "F: X; \r\n " + VASSERT_EQ( + "2.no-encoding", + "F: X; \r\n " "param1=abcdefghijkl", - p2.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 25)); // max line length = 25 + p2.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 25) // max line length = 25 + ); - VASSERT_EQ("2.rfc2047", "F: X; \r\n " + VASSERT_EQ( + "2.rfc2047", + "F: X; \r\n " "param1=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", - p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 25)); // max line length = 25 + p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 25) // max line length = 25 + ); - VASSERT_EQ("2.rfc2231", "F: X; \r\n " + VASSERT_EQ( + "2.rfc2231", + "F: X; \r\n " "param1*0*=charset''abc;\r\n " "param1*1*=defghijkl;\r\n " "param1*2*=mnopqrstu;\r\n " @@ -346,9 +387,12 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) "param1*4*=EFGHIJKLM;\r\n " "param1*5*=NOPQRSTUV;\r\n " "param1*6*=WXYZ", - p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 25)); // max line length = 25 + p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 25) // max line length = 25 + ); - VASSERT_EQ("2.both", "F: X; \r\n " + VASSERT_EQ( + "2.both", + "F: X; \r\n " "param1=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;\r\n " "param1*0*=charset''abc;\r\n " "param1*1*=defghijkl;\r\n " @@ -357,26 +401,41 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) "param1*4*=EFGHIJKLM;\r\n " "param1*5*=NOPQRSTUV;\r\n " "param1*6*=WXYZ", - p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 25)); // max line length = 25 + p2.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 25) // max line length = 25 + ); // Non-ASCII parameter value parameterizedHeaderField p3; - p3.appendParameter(vmime::make_shared ("param1", - vmime::word("δσσσσσσσσσσσσσσσσσσσσδσδα δσαδσδσαδσαδασδασ δσαδασδσα δσαδασδσα δασδασδασ δασαχφδδσα 2008.doc", - vmime::charset("utf-8")))); + p3.appendParameter( + vmime::make_shared ( + "param1", + vmime::word( + "δσσσσσσσσσσσσσσσσσσσσδσδα δσαδσδσαδσαδασδασ δσαδασδσα δσαδασδσα δασδασδασ δασαχφδδσα 2008.doc", + vmime::charset("utf-8") + ) + ) + ); - VASSERT_EQ("3.no-encoding", "F: X; \r\n " + VASSERT_EQ( + "3.no-encoding", + "F: X; \r\n " "param1=\" 2008.doc\"", - p3.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 80)); // max line length = 80 + p3.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING, 80) // max line length = 80 + ); - VASSERT_EQ("3.7bit-only", "F: X; \r\n " + VASSERT_EQ( + "3.7bit-only", + "F: X; \r\n " "param1=\"=?utf-8?B?zrTPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+DzrTPg860?=\r\n " "=?utf-8?B?zrEgzrTPg86xzrTPg860z4POsc60z4POsc60zrHPg860zrHPgyDOtM+DzrHOtM6x?=\r\n " "=?utf-8?B?z4POtM+DzrEgzrTPg86xzrTOsc+DzrTPg86xIM60zrHPg860zrHPg860zrHPgyDOtA==?=\r\n " "=?utf-8?B?zrHPg86xz4fPhs60zrTPg86xIDIwMDguZG9j?=\"", - p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 80)); // max line length = 80 + p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY, 80) // max line length = 80 + ); - VASSERT_EQ("3.both", "F: X; \r\n " + VASSERT_EQ( + "3.both", + "F: X; \r\n " "param1=\"=?utf-8?B?zrTPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+Dz4PPg8+DzrTPg860?=\r\n " "=?utf-8?B?zrEgzrTPg86xzrTPg860z4POsc60z4POsc60zrHPg860zrHPgyDOtM+DzrHOtM6x?=\r\n " "=?utf-8?B?z4POtM+DzrEgzrTPg86xzrTOsc+DzrTPg86xIM60zrHPg860zrHPg860zrHPgyDOtA==?=\r\n " @@ -389,9 +448,12 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) "param1*5*=%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CE%B1%CF%83;\r\n " "param1*6*=%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20%CE%B4%CE%B1%CF%83%CE%B1%CF;\r\n " "param1*7*=%87%CF%86%CE%B4%CE%B4%CF%83%CE%B1%202008.doc", - p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 80)); // max line length = 80 + p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047, 80) // max line length = 80 + ); - VASSERT_EQ("3.either", "F: X; param1*0*=utf-8''%CE%B4%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n " + VASSERT_EQ( + "3.either", + "F: X; param1*0*=utf-8''%CE%B4%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n " "param1*1*=%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83%CF%83;\r\n " "param1*2*=%CE%B4%CF%83%CE%B4%CE%B1%20%CE%B4%CF%83%CE%B1%CE%B4%CF%83%CE%B4%CF;\r\n " "param1*3*=%83%CE%B1%CE%B4%CF%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20;\r\n " @@ -399,47 +461,77 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) "param1*5*=%83%CE%B1%CE%B4%CE%B1%CF%83%CE%B4%CF%83%CE%B1%20%CE%B4%CE%B1%CF%83;\r\n " "param1*6*=%CE%B4%CE%B1%CF%83%CE%B4%CE%B1%CF%83%20%CE%B4%CE%B1%CF%83%CE%B1%CF;\r\n " "param1*7*=%87%CF%86%CE%B4%CE%B4%CF%83%CE%B1%202008.doc", - p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 80)); // max line length = 80 + p3.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY, 80) // max line length = 80 + ); // No encoding needed parameterizedHeaderField p4; - p4.appendParameter(vmime::make_shared ("param1", - vmime::word("va lue", vmime::charset("charset")))); + p4.appendParameter( + vmime::make_shared ( + "param1", + vmime::word("va lue", vmime::charset("charset")) + ) + ); - VASSERT_EQ("4.no-encoding", "F: X; param1=\"va lue\"", - p4.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING)); + VASSERT_EQ( + "4.no-encoding", + "F: X; param1=\"va lue\"", + p4.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING) + ); - VASSERT_EQ("4.rfc2047", "F: X; param1=\"va lue\"", - p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY)); + VASSERT_EQ( + "4.rfc2047", + "F: X; param1=\"va lue\"", + p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY) + ); - VASSERT_EQ("4.rfc2231", "F: X; param1=\"va lue\"", - p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY)); + VASSERT_EQ( + "4.rfc2231", + "F: X; param1=\"va lue\"", + p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY) + ); - VASSERT_EQ("4.both", "F: X; param1=\"va lue\"", - p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047)); + VASSERT_EQ( + "4.both", + "F: X; param1=\"va lue\"", + p4.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047) + ); // Language specification parameterizedHeaderField p5; - p5.appendParameter(vmime::make_shared ("param1", - vmime::word("This is ***fun***", vmime::charset("us-ascii"), "en-us"))); + p5.appendParameter( + vmime::make_shared ("param1", + vmime::word("This is ***fun***", vmime::charset("us-ascii"), "en-us")) + ); - VASSERT_EQ("5.no-encoding", "F: X; param1=\"This is ***fun***\"", - p5.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING)); + VASSERT_EQ( + "5.no-encoding", + "F: X; param1=\"This is ***fun***\"", + p5.generate(vmime::generationContext::PARAMETER_VALUE_NO_ENCODING) + ); - VASSERT_EQ("5.rfc2047", "F: X; param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\"", - p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY)); + VASSERT_EQ( + "5.rfc2047", + "F: X; param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\"", + p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2047_ONLY) + ); - VASSERT_EQ("5.rfc2231", "F: X; param1*=us-ascii''This%20is%20***fun***", - p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY)); + VASSERT_EQ( + "5.rfc2231", + "F: X; param1*=us-ascii''This%20is%20***fun***", + p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_ONLY) + ); - VASSERT_EQ("5.both", "F: X; " - "param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\";\r\n " - "param1*=us-ascii''This%20is%20***fun***", + VASSERT_EQ( + "5.both", + "F: X; " + "param1=\"=?us-ascii*en-us?Q?This_is_***fun***?=\";\r\n " + "param1*=us-ascii''This%20is%20***fun***", p5.generate(vmime::generationContext::PARAMETER_VALUE_RFC2231_AND_RFC2047)); } - void testGetGeneratedSizeRFC2231() - { + void testGetGeneratedSizeRFC2231() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); // Extended parameter with charset specifier @@ -543,12 +635,12 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) VASSERT("5.both", p5.getGeneratedSize(ctx) >= generateParameter(p5, ctx).length()); } - void testNonStandardEncodedParam() - { + void testNonStandardEncodedParam() { + // 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?=" parameterizedHeaderField p1; @@ -567,8 +659,8 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) } // Parse parameters with non-significant whitespaces - void testParseNonSignificantWS() - { + void testParseNonSignificantWS() { + parameterizedHeaderField p1; p1.parse(" \t X \r\n"); @@ -584,8 +676,8 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) } // Encode "tspecials" - void testEncodeTSpecials() - { + void testEncodeTSpecials() { + VASSERT_EQ(" 1", "p=\"val(ue\"", vmime::make_shared ("p", "val(ue")->generate()); VASSERT_EQ(" 2", "p=\"val)ue\"", vmime::make_shared ("p", "val)ue")->generate()); VASSERT_EQ(" 3", "p=\"val("p", "valgenerate()); @@ -604,16 +696,20 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) } // http://sourceforge.net/projects/vmime/forums/forum/237356/topic/3812278 - void testEncodeTSpecialsInRFC2231() - { - VASSERT_EQ("1", "filename*=UTF-8''my_file_name_%C3%B6%C3%A4%C3%BC_%281%29.txt", - vmime::make_shared - ("filename", - vmime::word("my_file_name_\xc3\xb6\xc3\xa4\xc3\xbc_(1).txt", "UTF-8"))->generate()); + void testEncodeTSpecialsInRFC2231() { + + VASSERT_EQ( + "1", + "filename*=UTF-8''my_file_name_%C3%B6%C3%A4%C3%BC_%281%29.txt", + vmime::make_shared ( + "filename", + vmime::word("my_file_name_\xc3\xb6\xc3\xa4\xc3\xbc_(1).txt", "UTF-8") + )->generate() + ); } - void testWhitespaceBreaksTheValue() - { + void testWhitespaceBreaksTheValue() { + parameterizedHeaderField p; p.parse("xxx yyy; param1=value1 \r\n"); @@ -624,4 +720,3 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/pathTest.cpp b/tests/parser/pathTest.cpp index f73dd0d4..13969112 100644 --- a/tests/parser/pathTest.cpp +++ b/tests/parser/pathTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,8 +33,8 @@ VMIME_TEST_SUITE_BEGIN(pathTest) VMIME_TEST_LIST_END - void testParse() - { + void testParse() { + vmime::path p1; p1.parse("<>"); @@ -54,8 +54,8 @@ VMIME_TEST_SUITE_BEGIN(pathTest) VASSERT_EQ("3.2", "domain", p3.getDomain()); } - void testParse2() - { + void testParse2() { + // Test some invalid paths (no '<>') vmime::path p1; p1.parse(""); @@ -76,8 +76,8 @@ VMIME_TEST_SUITE_BEGIN(pathTest) VASSERT_EQ("3.2", "domain", p3.getDomain()); } - void testGenerate() - { + void testGenerate() { + vmime::path p1; VASSERT_EQ("1", "<>", p1.generate()); @@ -100,4 +100,3 @@ VMIME_TEST_SUITE_BEGIN(pathTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/streamContentHandlerTest.cpp b/tests/parser/streamContentHandlerTest.cpp index 55680c93..399118e7 100644 --- a/tests/parser/streamContentHandlerTest.cpp +++ b/tests/parser/streamContentHandlerTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,15 +41,15 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VMIME_TEST_LIST_END - void testIsEmpty() - { + void testIsEmpty() { + vmime::streamContentHandler cth; VASSERT_TRUE("empty", cth.isEmpty()); } - void testGetLength() - { + void testGetLength() { + vmime::string data("Test Data"); vmime::shared_ptr stream = vmime::make_shared (data); @@ -60,8 +60,8 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VASSERT_EQ("length", 9, cth.getLength()); } - void testIsEncoded() - { + void testIsEncoded() { + vmime::string data("Test Data"); vmime::shared_ptr stream = vmime::make_shared (data); @@ -82,8 +82,8 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VASSERT_EQ("encoding", "base64", cth2.getEncoding().generate()); } - void testGetLength_Encoded() - { + void testGetLength_Encoded() { + vmime::string data("foo=12=34=56bar"); vmime::shared_ptr stream = vmime::make_shared (data); @@ -94,8 +94,8 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VASSERT_EQ("length", 15, cth.getLength()); } - void testExtract() - { + void testExtract() { + vmime::string data("Test Data"); vmime::shared_ptr stream = vmime::make_shared (data); @@ -110,10 +110,12 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VASSERT_EQ("extract", "Test Data", oss.str()); } - void testExtract_Encoded() - { - vmime::string data - ("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk="); + void testExtract_Encoded() { + + vmime::string data( + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=" + ); + vmime::shared_ptr stream = vmime::make_shared (data); @@ -125,14 +127,18 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) cth.extract(osa); // Data should be decoded from B64 - VASSERT_EQ("extract", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", oss.str()); + VASSERT_EQ( + "extract", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + oss.str() + ); } void testExtractRaw_Encoded() { - vmime::string data - ("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk="); + vmime::string data( + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=" + ); vmime::shared_ptr stream = vmime::make_shared (data); @@ -144,12 +150,15 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) cth.extractRaw(osa); // Data should not be decoded - VASSERT_EQ("extractRaw", - "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", oss.str()); + VASSERT_EQ( + "extractRaw", + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", + oss.str() + ); } - void testGenerate() - { + void testGenerate() { + vmime::string data("foo\x12\x34\x56 bar"); vmime::shared_ptr stream = vmime::make_shared (data); @@ -165,8 +174,8 @@ VMIME_TEST_SUITE_BEGIN(streamContentHandlerTest) VASSERT_EQ("generate", "Zm9vEjRWIGJhcg==", oss.str()); } - void testGenerate_Encoded() - { + void testGenerate_Encoded() { + vmime::string data("foo=12=34=56bar"); vmime::shared_ptr stream = vmime::make_shared (data); diff --git a/tests/parser/stringContentHandlerTest.cpp b/tests/parser/stringContentHandlerTest.cpp index e238e172..0f886f76 100644 --- a/tests/parser/stringContentHandlerTest.cpp +++ b/tests/parser/stringContentHandlerTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -42,23 +42,23 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) VMIME_TEST_LIST_END - void testIsEmpty() - { + void testIsEmpty() { + vmime::stringContentHandler cth; VASSERT_TRUE("empty", cth.isEmpty()); } - void testGetLength() - { + void testGetLength() { + vmime::stringContentHandler cth("Test Data"); VASSERT_FALSE("empty", cth.isEmpty()); VASSERT_EQ("length", 9, cth.getLength()); } - void testIsEncoded() - { + void testIsEncoded() { + vmime::stringContentHandler cth("Test Data"); VASSERT_FALSE("encoded", cth.isEncoded()); @@ -71,17 +71,19 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) VASSERT_EQ("encoding", "base64", cth2.getEncoding().generate()); } - void testGetLength_Encoded() - { - vmime::stringContentHandler cth - ("foo=12=34=56bar", vmime::encoding("quoted-printable")); + void testGetLength_Encoded() { + + vmime::stringContentHandler cth( + "foo=12=34=56bar", + vmime::encoding("quoted-printable") + ); // Reported length should be the length of encoded data VASSERT_EQ("length", 15, cth.getLength()); } - void testExtract() - { + void testExtract() { + vmime::stringContentHandler cth("Test Data"); std::ostringstream oss; @@ -92,11 +94,12 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) VASSERT_EQ("extract", "Test Data", oss.str()); } - void testExtract_Encoded() - { - vmime::stringContentHandler cth - ("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", - vmime::encoding("base64")); + void testExtract_Encoded() { + + vmime::stringContentHandler cth( + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", + vmime::encoding("base64") + ); std::ostringstream oss; vmime::utility::outputStreamAdapter osa(oss); @@ -104,15 +107,19 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) cth.extract(osa); // Data should be decoded from B64 - VASSERT_EQ("extract", - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", oss.str()); + VASSERT_EQ( + "extract", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + oss.str() + ); } - void testExtractRaw_Encoded() - { - vmime::stringContentHandler cth - ("QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", - vmime::encoding("base64")); + void testExtractRaw_Encoded() { + + vmime::stringContentHandler cth( + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", + vmime::encoding("base64") + ); std::ostringstream oss; vmime::utility::outputStreamAdapter osa(oss); @@ -120,12 +127,15 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) cth.extractRaw(osa); // Data should not be decoded - VASSERT_EQ("extractRaw", - "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", oss.str()); + VASSERT_EQ( + "extractRaw", + "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODk=", + oss.str() + ); } - void testGenerate() - { + void testGenerate() { + vmime::stringContentHandler cth("foo\x12\x34\x56 bar"); std::ostringstream oss; @@ -137,10 +147,12 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) VASSERT_EQ("generate", "Zm9vEjRWIGJhcg==", oss.str()); } - void testGenerate_Encoded() - { - vmime::stringContentHandler cth - ("foo=12=34=56bar", vmime::encoding("quoted-printable")); + void testGenerate_Encoded() { + + vmime::stringContentHandler cth( + "foo=12=34=56bar", + vmime::encoding("quoted-printable") + ); std::ostringstream oss; vmime::utility::outputStreamAdapter osa(oss); @@ -151,8 +163,8 @@ VMIME_TEST_SUITE_BEGIN(stringContentHandlerTest) VASSERT_EQ("generate", "Zm9vEjRWYmFy", oss.str()); } - void testStringProxy() - { + void testStringProxy() { + // With 'stringProxy' object vmime::utility::stringProxy str("This is the data buffer", 12, 12 + 4); vmime::stringContentHandler cth(str); diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp index 60a9508e..16abf11b 100644 --- a/tests/parser/textTest.cpp +++ b/tests/parser/textTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -66,48 +66,46 @@ VMIME_TEST_SUITE_BEGIN(textTest) VMIME_TEST_LIST_END - static const vmime::string getDisplayText(const vmime::text& t) - { + static const vmime::string getDisplayText(const vmime::text& t) { + return t.getWholeBuffer(); } - static const vmime::string cleanGeneratedWords(const std::string& str) - { + static const vmime::string cleanGeneratedWords(const std::string& str) { + std::istringstream iss(str); std::string res; std::string x; - while (std::getline(iss, x)) + while (std::getline(iss, x)) { res += vmime::utility::stringUtils::trim(x); + } return res; } - void setUp() - { + 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 - { + try { std::locale::global(std::locale("")); - } - catch (std::exception &) - { + } catch (std::exception &) { std::setlocale(LC_ALL, ""); } } - void tearDown() - { + void tearDown() { + // Restore default locale std::locale::global(std::locale("C")); } - void testConstructors() - { + void testConstructors() { + vmime::text t1; VASSERT_EQ("1.1", 0, t1.getWordCount()); @@ -143,8 +141,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("5.5", w2.getCharset(), t5.getWordAt(1)->getCharset()); } - void testCopy() - { + void testCopy() { + vmime::text t1("Test: \xa9\xc3"); VASSERT("operator==", t1 == t1); @@ -156,8 +154,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT("copyFrom", t1 == t2); } - void testNewFromString() - { + void testNewFromString() { + vmime::string s1 = "only ASCII characters"; vmime::charset c1("test"); vmime::text t1; @@ -186,52 +184,75 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset()); } - static const vmime::string parseText(const vmime::string& buffer) - { + static const vmime::string parseText(const vmime::string& buffer) { + vmime::text t; t.parse(buffer); std::ostringstream oss; oss << t; - return (oss.str()); + return oss.str(); } - void testParse() - { + void testParse() { + // From RFC-2047 - VASSERT_EQ("1", "[text: [[word: charset=US-ASCII, buffer=Keith Moore]]]", - parseText("=?US-ASCII?Q?Keith_Moore?=")); + VASSERT_EQ( + "1", + "[text: [[word: charset=US-ASCII, buffer=Keith Moore]]]", + parseText("=?US-ASCII?Q?Keith_Moore?=") + ); - VASSERT_EQ("2", "[text: [[word: charset=ISO-8859-1, buffer=Keld J\xf8rn Simonsen]]]", - parseText("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=")); + VASSERT_EQ( + "2", + "[text: [[word: charset=ISO-8859-1, buffer=Keld J\xf8rn Simonsen]]]", + parseText("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=") + ); - VASSERT_EQ("3", "[text: [[word: charset=ISO-8859-1, buffer=Andr\xe9]," \ - "[word: charset=us-ascii, buffer= Pirard]]]", - parseText("=?ISO-8859-1?Q?Andr=E9?= Pirard")); + VASSERT_EQ( + "3", + "[text: [[word: charset=ISO-8859-1, buffer=Andr\xe9]," \ + "[word: charset=us-ascii, buffer= Pirard]]]", + parseText("=?ISO-8859-1?Q?Andr=E9?= Pirard") + ); - VASSERT_EQ("4", "[text: [[word: charset=ISO-8859-1, buffer=If you can read this yo]," \ - "[word: charset=ISO-8859-2, buffer=u understand the example.]]]", - parseText("=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " \ - "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=")); + VASSERT_EQ( + "4", + "[text: [[word: charset=ISO-8859-1, buffer=If you can read this yo]," \ + "[word: charset=ISO-8859-2, buffer=u understand the example.]]]", + parseText( + "=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " \ + "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=" + ) + ); // Bugfix: in "=?charset?q?=XX=YY?=", the "?=" finish // sequence was not correctly found (should be the one // after '=YY' and not the one after '?q'). - VASSERT_EQ("5", "[text: [[word: charset=abc, buffer=\xe9\xe9]]]", - parseText("=?abc?q?=E9=E9?=")); + VASSERT_EQ( + "5", + "[text: [[word: charset=abc, buffer=\xe9\xe9]]]", + parseText("=?abc?q?=E9=E9?=") + ); // Question marks (?) in the middle of the string - VASSERT_EQ("6", "[text: [[word: charset=iso-8859-1, buffer=Know wh\xe4t? It works!]]]", - parseText("=?iso-8859-1?Q?Know_wh=E4t?_It_works!?=")); + VASSERT_EQ( + "6", + "[text: [[word: charset=iso-8859-1, buffer=Know wh\xe4t? It works!]]]", + parseText("=?iso-8859-1?Q?Know_wh=E4t?_It_works!?=") + ); // With language specifier - VASSERT_EQ("7", "[text: [[word: charset=US-ASCII, buffer=Keith Moore, lang=EN]]]", - parseText("=?US-ASCII*EN?Q?Keith_Moore?=")); + VASSERT_EQ( + "7", + "[text: [[word: charset=US-ASCII, buffer=Keith Moore, lang=EN]]]", + parseText("=?US-ASCII*EN?Q?Keith_Moore?=") + ); } - void testGenerate() - { + void testGenerate() { + // TODO // With language specifier @@ -242,8 +263,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("lang2", "=?US-ASCII*EN?Q?Keith_Moore?=", wlang2.generate()); } - void testDisplayForm() - { + void testDisplayForm() { + #define DISPLAY_FORM(x) getDisplayText(*vmime::text::decodeAndUnfold(x)) // From RFC-2047 @@ -276,8 +297,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) #undef DISPLAY_FORM } - void testWordConstructors() - { + void testWordConstructors() { + VASSERT_EQ("1.1", vmime::charset::getLocalCharset(), vmime::word().getCharset()); VASSERT_EQ("1.2", "", vmime::word().getBuffer()); @@ -288,8 +309,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("3.2", "foo", vmime::word("foo", vmime::charset("bar")).getBuffer()); } - void testWordParse() - { + void testWordParse() { + // Simple encoded word vmime::word w1; w1.parse("=?foo?q?bar=E9 baz?="); @@ -319,21 +340,32 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("4.2", "=?whatever?not_q_or_b?whatever?=", w4.getBuffer()); } - void testWordGenerate() - { - VASSERT_EQ("1", "=?foo?Q?bar=E9_baz?=", - vmime::word("bar\xe9 baz", vmime::charset("foo")).generate()); + void testWordGenerate() { - VASSERT_EQ("2", "=?foo?B?8fLz9PU=?=", - vmime::word("\xf1\xf2\xf3\xf4\xf5", vmime::charset("foo")).generate()); + VASSERT_EQ( + "1", + "=?foo?Q?bar=E9_baz?=", + vmime::word("bar\xe9 baz", vmime::charset("foo")).generate() + ); + + VASSERT_EQ( + "2", + "=?foo?B?8fLz9PU=?=", + vmime::word("\xf1\xf2\xf3\xf4\xf5", vmime::charset("foo")).generate() + ); } - void testWordGenerateSpace() - { + void testWordGenerateSpace() { + // No white-space between an unencoded word and a encoded one - VASSERT_EQ("1", "Bonjour =?utf-8?Q?Fran=C3=A7ois?=", - vmime::text::newFromString("Bonjour Fran\xc3\xa7ois", - vmime::charset("utf-8"))->generate()); + VASSERT_EQ( + "1", + "Bonjour =?utf-8?Q?Fran=C3=A7ois?=", + vmime::text::newFromString( + "Bonjour Fran\xc3\xa7ois", + vmime::charset("utf-8") + )->generate() + ); // White-space between two encoded words vmime::text txt; @@ -356,8 +388,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("4", encoded, txt2.generate()); } - void testWordGenerateSpace2() - { + void testWordGenerateSpace2() { + // White-space between two encoded words (#2) vmime::text txt; txt.appendWord(vmime::make_shared ("Facture ", "utf-8")); @@ -382,18 +414,28 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("3", encoded, txt2.generate()); } - void testWordGenerateMultiBytes() - { - // Ensure we don't encode a non-integral number of characters - VASSERT_EQ("1", "=?utf-8?Q?aaa?==?utf-8?Q?=C3=A9?==?utf-8?Q?zzz?=", - cleanGeneratedWords(vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(16))); + void testWordGenerateMultiBytes() { - VASSERT_EQ("2", "=?utf-8?Q?aaa=C3=A9?==?utf-8?Q?zzz?=", - cleanGeneratedWords(vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(17))); + // Ensure we don't encode a non-integral number of characters + VASSERT_EQ( + "1", + "=?utf-8?Q?aaa?==?utf-8?Q?=C3=A9?==?utf-8?Q?zzz?=", + cleanGeneratedWords( + vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(16) + ) + ); + + VASSERT_EQ( + "2", + "=?utf-8?Q?aaa=C3=A9?==?utf-8?Q?zzz?=", + cleanGeneratedWords( + vmime::word("aaa\xc3\xa9zzz", vmime::charset("utf-8")).generate(17) + ) + ); } - void testWordGenerateQuote() - { + void testWordGenerateQuote() { + std::string str; vmime::utility::outputStreamStringAdapter os(str); @@ -402,37 +444,56 @@ VMIME_TEST_SUITE_BEGIN(textTest) // ASCII-only text is quotable str.clear(); - vmime::word("Quoted text").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + vmime::word("Quoted text") + .generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + VASSERT_EQ("1", "\"Quoted text\"", cleanGeneratedWords(str)); // Text with CR/LF is not quotable str.clear(); - vmime::word("Non-quotable\ntext", "us-ascii").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + vmime::word("Non-quotable\ntext", "us-ascii") + .generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + VASSERT_EQ("2", "=?us-ascii?Q?Non-quotable=0Atext?=", cleanGeneratedWords(str)); // Text with non-ASCII chars is not quotable str.clear(); - vmime::word("Non-quotable text \xc3\xa9").generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + vmime::word("Non-quotable text \xc3\xa9") + .generate(ctx, os, 0, NULL, vmime::text::QUOTE_IF_POSSIBLE, NULL); + VASSERT_EQ("3", "=?UTF-8?Q?Non-quotable_text_=C3=A9?=", cleanGeneratedWords(str)); } - void testWordGenerateSpecialCharsets() - { + void testWordGenerateSpecialCharsets() { + // ISO-2022-JP only uses 7-bit chars but should be encoded in Base64 - VASSERT_EQ("1", "=?iso-2022-jp?B?XlskQiVRITwlPSVKJWshJiU9JVUlSCUmJSclIl5bKEI=?=", - cleanGeneratedWords(vmime::word("^[$B%Q!<%=%J%k!&%=%U%H%&%'%\"^[(B", - vmime::charset("iso-2022-jp")).generate(100))); + VASSERT_EQ( + "1", + "=?iso-2022-jp?B?XlskQiVRITwlPSVKJWshJiU9JVUlSCUmJSclIl5bKEI=?=", + cleanGeneratedWords( + vmime::word( + "^[$B%Q!<%=%J%k!&%=%U%H%&%'%\"^[(B", + vmime::charset("iso-2022-jp") + ).generate(100) + ) + ); } - void testWordGenerateSpecials() - { + void testWordGenerateSpecials() { + // In RFC-2047, quotation marks (ASCII 22h) should be encoded - VASSERT_EQ("1", "=?UTF-8?Q?=22=C3=9Cml=C3=A4ute=22?=", - vmime::word("\x22\xC3\x9Cml\xC3\xA4ute\x22", vmime::charset("UTF-8")).generate()); + VASSERT_EQ( + "1", + "=?UTF-8?Q?=22=C3=9Cml=C3=A4ute=22?=", + vmime::word( + "\x22\xC3\x9Cml\xC3\xA4ute\x22", + vmime::charset("UTF-8") + ).generate() + ); } - void testWhitespace() - { + void testWhitespace() { + // Create vmime::text text; text.createFromString("Achim Br\xc3\xa4ndt", vmime::charsets::UTF_8); @@ -456,8 +517,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("11", "utf-8", text.getWordAt(1)->getCharset()); } - void testWhitespaceMBox() - { + void testWhitespaceMBox() { + // Space MUST be encoded inside a word vmime::mailbox mbox(vmime::text("Achim Br\xc3\xa4ndt", vmime::charsets::UTF_8), "me@vmime.org"); VASSERT_EQ("generate1", "=?us-ascii?Q?Achim_?= =?utf-8?Q?Br=C3=A4ndt?= ", mbox.generate()); @@ -478,30 +539,38 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("parse.email", "me@vmime.org", mbox.getEmail()); } - void testFoldingAscii() - { + void testFoldingAscii() { + // In this test, no encoding is needed, but line should be folded anyway vmime::word w("01234567890123456789012345678901234567890123456789" "01234567890123456789012345678901234567890123456789", vmime::charset("us-ascii")); - VASSERT_EQ("fold.ascii", + VASSERT_EQ( + "fold.ascii", "=?us-ascii?Q?01234567890123456789012345678901234?=\r\n" " =?us-ascii?Q?5678901234567890123456789012345678?=\r\n" - " =?us-ascii?Q?9012345678901234567890123456789?=", w.generate(50)); + " =?us-ascii?Q?9012345678901234567890123456789?=", w.generate(50) + ); } - void testForcedNonEncoding() - { + void testForcedNonEncoding() { + // Testing long unbreakable and unencodable header vmime::relay r; - r.parse(" from User (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1]) by servername.hostname.com\n\t" - "with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009 09:23:49 +0100"); + r.parse( + " from User (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1]) by servername.hostname.com\n\t" + "with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009 09:23:49 +0100" + ); - VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78)); + VASSERT_EQ( + "received.long", + "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", + r.generate(78) + ); } - void testBugFix20110511() - { + void testBugFix20110511() { + /* Using the latest version of vmime (0.9.1), encoding the following string: Jean @@ -520,8 +589,11 @@ VMIME_TEST_SUITE_BEGIN(textTest) const std::string ENCODED_TEXT = "Jean =?utf-8?Q?Gwena=C3=ABl?= Dutourd"; // Encode - VASSERT_EQ("encode", ENCODED_TEXT, - vmime::text::newFromString(DECODED_TEXT, vmime::charset("utf-8"))->generate()); + VASSERT_EQ( + "encode", + ENCODED_TEXT, + vmime::text::newFromString(DECODED_TEXT, vmime::charset("utf-8"))->generate() + ); // Decode vmime::text t; @@ -529,56 +601,69 @@ VMIME_TEST_SUITE_BEGIN(textTest) // -- words std::ostringstream oss; oss << t; - VASSERT_EQ("decode1", + VASSERT_EQ( + "decode1", "[text: [[word: charset=us-ascii, buffer=Jean ]," "[word: charset=utf-8, buffer=Gwenaël]," - "[word: charset=us-ascii, buffer= Dutourd]]]", oss.str()); + "[word: charset=us-ascii, buffer= Dutourd]]]", + oss.str() + ); // -- getWholeBuffer VASSERT_EQ("decode2", DECODED_TEXT, t.getWholeBuffer()); } - void testInternationalizedEmail_specialChars() - { + void testInternationalizedEmail_specialChars() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(true); vmime::generationContext::switcher contextSwitcher(ctx); // Special sequence/chars should still be encoded - VASSERT_EQ("1", "=?us-ascii?Q?Test=3D=3Frfc2047_sequence?=", - vmime::word("Test=?rfc2047 sequence", vmime::charset("us-ascii")).generate()); + VASSERT_EQ( + "1", + "=?us-ascii?Q?Test=3D=3Frfc2047_sequence?=", + vmime::word("Test=?rfc2047 sequence", vmime::charset("us-ascii")).generate() + ); - VASSERT_EQ("2", "=?us-ascii?Q?Line_One=0ALine_Two?=", - vmime::word("Line One\nLine Two", vmime::charset("us-ascii")).generate()); + VASSERT_EQ( + "2", + "=?us-ascii?Q?Line_One=0ALine_Two?=", + vmime::word("Line One\nLine Two", vmime::charset("us-ascii")).generate() + ); } - void testInternationalizedEmail_UTF8() - { + void testInternationalizedEmail_UTF8() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(true); vmime::generationContext::switcher contextSwitcher(ctx); // Already UTF-8 encoded text should be left as is - VASSERT_EQ("1", "Achim Br\xc3\xa4ndt", - vmime::word("Achim Br\xc3\xa4ndt", vmime::charset("utf-8")).generate()); + VASSERT_EQ( + "1", "Achim Br\xc3\xa4ndt", + vmime::word("Achim Br\xc3\xa4ndt", vmime::charset("utf-8")).generate() + ); } - void testInternationalizedEmail_nonUTF8() - { + void testInternationalizedEmail_nonUTF8() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(true); vmime::generationContext::switcher contextSwitcher(ctx); // Non UTF-8 encoded text should first be converted to UTF-8 - VASSERT_EQ("1", "Achim Br\xc3\xa4ndt", - vmime::word("Achim Br\xe4ndt", vmime::charset("iso-8859-1")).generate()); + VASSERT_EQ( + "1", "Achim Br\xc3\xa4ndt", + vmime::word("Achim Br\xe4ndt", vmime::charset("iso-8859-1")).generate() + ); } - void testInternationalizedEmail_folding() - { + void testInternationalizedEmail_folding() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(true); @@ -588,63 +673,82 @@ VMIME_TEST_SUITE_BEGIN(textTest) vmime::word w1("01234567890123456789\xc3\xa0x012345678901234567890123456789" "01234567890123456789\xc3\xa0x012345678901234567890123456789", vmime::charset("utf-8")); - VASSERT_EQ("1", + VASSERT_EQ( + "1", "=?utf-8?Q?01234567890123456789=C3=A0x01234567890?=\r\n" " =?utf-8?Q?1234567890123456789012345678901234567?=\r\n" " =?utf-8?Q?89=C3=A0x0123456789012345678901234567?=\r\n" - " =?utf-8?Q?89?=", w1.generate(50)); + " =?utf-8?Q?89?=", + w1.generate(50) + ); // RFC-2047 encoding will not be forced, as words can be wrapped in a new line vmime::word w2("bla bla bla This is some '\xc3\xa0\xc3\xa7' UTF-8 encoded text", vmime::charset("utf-8")); - VASSERT_EQ("2", + VASSERT_EQ( + "2", "bla bla bla This is\r\n" " some '\xc3\xa0\xc3\xa7' UTF-8\r\n" - " encoded text", w2.generate(20)); + " encoded text", + w2.generate(20) + ); } - void testWronglyPaddedB64Words() - { + void testWronglyPaddedB64Words() { + vmime::text outText; vmime::text::decodeAndUnfold("=?utf-8?B?5Lit5?=\n =?utf-8?B?paH?=", &outText); - VASSERT_EQ("1", "\xe4\xb8\xad\xe6\x96\x87", - outText.getConvertedText(vmime::charset("utf-8"))); + VASSERT_EQ( + "1", + "\xe4\xb8\xad\xe6\x96\x87", + outText.getConvertedText(vmime::charset("utf-8")) + ); vmime::text::decodeAndUnfold("=?utf-8?B?5Lit5p?=\n =?utf-8?B?aH?=", &outText); - VASSERT_EQ("2", "\xe4\xb8\xad\xe6\x96\x87", - outText.getConvertedText(vmime::charset("utf-8"))); + VASSERT_EQ( + "2", + "\xe4\xb8\xad\xe6\x96\x87", + outText.getConvertedText(vmime::charset("utf-8")) + ); vmime::text::decodeAndUnfold("=?utf-8?B?5Lit5pa?=\n =?utf-8?B?H?=", &outText); - VASSERT_EQ("3", "\xe4\xb8\xad\xe6\x96\x87", - outText.getConvertedText(vmime::charset("utf-8"))); + VASSERT_EQ( + "3", + "\xe4\xb8\xad\xe6\x96\x87", + outText.getConvertedText(vmime::charset("utf-8")) + ); } // Ensure that words which encode a non-integral number of characters // are correctly decoded. - void testFixBrokenWords() - { + void testFixBrokenWords() { + vmime::text outText; vmime::charsetConverterOptions opts; opts.silentlyReplaceInvalidSequences = false; // just to be sure that broken words are actually fixed // Test case 1 - vmime::text::decodeAndUnfold - ("=?utf-8?Q?Gwena=C3?=" - "=?utf-8?Q?=ABl?=", &outText); + vmime::text::decodeAndUnfold( + "=?utf-8?Q?Gwena=C3?=" + "=?utf-8?Q?=ABl?=", + &outText + ); VASSERT_EQ("1.1", 1, outText.getWordCount()); VASSERT_EQ("1.2", "Gwena\xc3\xabl", outText.getWordAt(0)->getBuffer()); VASSERT_EQ("1.3", vmime::charset("utf-8"), outText.getWordAt(0)->getCharset()); // Test case 2 - vmime::text::decodeAndUnfold - ("=?utf-8?B?5Lit6Yu85qmf5qKw6JGj5LqL5pyDMTAz5bm056ysMDXlsYbn?=" - "=?utf-8?B?rKwwN+asoeitsOeoiw==?=", &outText); + vmime::text::decodeAndUnfold( + "=?utf-8?B?5Lit6Yu85qmf5qKw6JGj5LqL5pyDMTAz5bm056ysMDXlsYbn?=" + "=?utf-8?B?rKwwN+asoeitsOeoiw==?=", + &outText + ); VASSERT_EQ("2.1", 1, outText.getWordCount()); VASSERT_EQ("2.2", "\xe4\xb8\xad\xe9\x8b\xbc\xe6\xa9\x9f\xe6\xa2\xb0" @@ -654,21 +758,25 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("2.3", vmime::charset("utf-8"), outText.getWordAt(0)->getCharset()); // Test case 3 (a character spanning over 3 words: 'を' = E3 82 92) - vmime::text::decodeAndUnfold - ("=?utf-8?Q?abc=E3?=" - "=?utf-8?Q?=82?=" - "=?utf-8?Q?=92xyz?=", &outText); + vmime::text::decodeAndUnfold( + "=?utf-8?Q?abc=E3?=" + "=?utf-8?Q?=82?=" + "=?utf-8?Q?=92xyz?=", + &outText + ); VASSERT_EQ("3.1", 1, outText.getWordCount()); VASSERT_EQ("3.2", "abc\xe3\x82\x92xyz", outText.getWordAt(0)->getBuffer()); VASSERT_EQ("3.3", vmime::charset("utf-8"), outText.getWordAt(0)->getCharset()); // Test case 4 (remains invalid) - vmime::text::decodeAndUnfold - ("=?utf-8?Q?abc=E3?=" - "=?utf-8?Q?=82?=" - "=?utf-8?Q?xy?=" - "=?utf-8?Q?z?=", &outText); + vmime::text::decodeAndUnfold( + "=?utf-8?Q?abc=E3?=" + "=?utf-8?Q?=82?=" + "=?utf-8?Q?xy?=" + "=?utf-8?Q?z?=", + &outText + ); VASSERT_EQ("4.1", 2, outText.getWordCount()); VASSERT_EQ("4.2", "abc", outText.getWordAt(0)->getBuffer()); @@ -677,11 +785,13 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("4.5", vmime::charset("utf-8"), outText.getWordAt(1)->getCharset()); // Test case 5 (remains partially invalid) - vmime::text::decodeAndUnfold - ("=?utf-8?Q?abc=E3?=" - "=?utf-8?Q?=82?=" - "=?utf-8?Q?\x92xy?=" - "=?utf-8?Q?z\xc3?=", &outText); + vmime::text::decodeAndUnfold( + "=?utf-8?Q?abc=E3?=" + "=?utf-8?Q?=82?=" + "=?utf-8?Q?\x92xy?=" + "=?utf-8?Q?z\xc3?=", + &outText + ); VASSERT_EQ("5.1", 2, outText.getWordCount()); VASSERT_EQ("5.2", "abc\xe3\x82\x92xyz", outText.getWordAt(0)->getBuffer()); @@ -690,8 +800,8 @@ VMIME_TEST_SUITE_BEGIN(textTest) VASSERT_EQ("5.5", vmime::charset("utf-8"), outText.getWordAt(1)->getCharset()); } - void testUnknownCharset() - { + void testUnknownCharset() { + vmime::text t; vmime::text::decodeAndUnfold("=?gb2312?B?wdaRY8PA?=", &t); @@ -721,4 +831,3 @@ VMIME_TEST_SUITE_BEGIN(textTest) } VMIME_TEST_SUITE_END - diff --git a/tests/parser/wordEncoderTest.cpp b/tests/parser/wordEncoderTest.cpp index c3c44a87..08d34aa4 100644 --- a/tests/parser/wordEncoderTest.cpp +++ b/tests/parser/wordEncoderTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -40,88 +40,133 @@ VMIME_TEST_SUITE_BEGIN(wordEncoderTest) VMIME_TEST_LIST_END - void testGetNextChunk() - { + void testGetNextChunk() { + // An integral number of characters should be encoded vmime::wordEncoder we( "bufferfoobarbaz", vmime::charset("utf-8"), - vmime::wordEncoder::ENCODING_AUTO); + vmime::wordEncoder::ENCODING_AUTO + ); VASSERT_EQ("1", "buffer", we.getNextChunk(6)); VASSERT_EQ("2", "foo", we.getNextChunk(3)); VASSERT_EQ("3", "barbaz", we.getNextChunk(10)); } - void testGetNextChunk_integral() - { + void testGetNextChunk_integral() { + // An integral number of characters should be encoded vmime::wordEncoder we( "buffer\xc3\xa0plop", vmime::charset("utf-8"), - vmime::wordEncoder::ENCODING_AUTO); + vmime::wordEncoder::ENCODING_AUTO + ); VASSERT_EQ("1", "buffer=C3=A0", we.getNextChunk(7)); VASSERT_EQ("2", "plop", we.getNextChunk(10)); } - void testIsEncodingNeeded_ascii() - { + void testIsEncodingNeeded_ascii() { + vmime::generationContext ctx(vmime::generationContext::getDefaultContext()); ctx.setInternationalizedEmailSupport(false); - VASSERT_FALSE("ascii", vmime::wordEncoder::isEncodingNeeded - (ctx, "ASCII-only buffer", vmime::charset("utf-8"), "")); + VASSERT_FALSE( + "ascii", + vmime::wordEncoder::isEncodingNeeded( + ctx, "ASCII-only buffer", vmime::charset("utf-8"), "" + ) + ); - VASSERT_TRUE("non-ascii", vmime::wordEncoder::isEncodingNeeded - (ctx, "Buffer with some UTF-8 '\xc3\xa0'", vmime::charset("utf-8"), "")); + VASSERT_TRUE( + "non-ascii", + vmime::wordEncoder::isEncodingNeeded( + ctx, "Buffer with some UTF-8 '\xc3\xa0'", vmime::charset("utf-8"), "" + ) + ); } - void testIsEncodingNeeded_withLanguage() - { - VASSERT_TRUE("ascii", vmime::wordEncoder::isEncodingNeeded - (vmime::generationContext::getDefaultContext(), "ASCII-only buffer", vmime::charset("utf-8"), "en")); + void testIsEncodingNeeded_withLanguage() { + + VASSERT_TRUE( + "ascii", + vmime::wordEncoder::isEncodingNeeded( + vmime::generationContext::getDefaultContext(), + "ASCII-only buffer", + vmime::charset("utf-8"), + "en" + ) + ); } - void testIsEncodingNeeded_specialChars() - { - VASSERT_TRUE("rfc2047", vmime::wordEncoder::isEncodingNeeded - (vmime::generationContext::getDefaultContext(), - "foo bar =? foo bar", vmime::charset("us-ascii"), "")); + void testIsEncodingNeeded_specialChars() { - VASSERT_TRUE("new line 1", vmime::wordEncoder::isEncodingNeeded - (vmime::generationContext::getDefaultContext(), - "foo bar \n foo bar", vmime::charset("us-ascii"), "")); + VASSERT_TRUE( + "rfc2047", + vmime::wordEncoder::isEncodingNeeded( + vmime::generationContext::getDefaultContext(), + "foo bar =? foo bar", + vmime::charset("us-ascii"), + "" + ) + ); - VASSERT_TRUE("new line 2", vmime::wordEncoder::isEncodingNeeded - (vmime::generationContext::getDefaultContext(), - "foo bar \r foo bar", vmime::charset("us-ascii"), "")); + VASSERT_TRUE( + "new line 1", + vmime::wordEncoder::isEncodingNeeded( + vmime::generationContext::getDefaultContext(), + "foo bar \n foo bar", + vmime::charset("us-ascii"), + "" + ) + ); + + VASSERT_TRUE( + "new line 2", + vmime::wordEncoder::isEncodingNeeded( + vmime::generationContext::getDefaultContext(), + "foo bar \r foo bar", + vmime::charset("us-ascii"), + "" + ) + ); } - void testGuessBestEncoding_QP() - { - VASSERT_EQ("1", vmime::wordEncoder::ENCODING_QP, - vmime::wordEncoder::guessBestEncoding("ASCII only buffer", vmime::charset("us-ascii"))); + void testGuessBestEncoding_QP() { + + VASSERT_EQ( + "1", + vmime::wordEncoder::ENCODING_QP, + vmime::wordEncoder::guessBestEncoding("ASCII only buffer", vmime::charset("us-ascii")) + ); } - void testGuessBestEncoding_B64() - { + void testGuessBestEncoding_B64() { + // >= 40% non-ASCII => Base64... - VASSERT_EQ("1", vmime::wordEncoder::ENCODING_B64, - vmime::wordEncoder::guessBestEncoding("xxxxx\xc3\xa0\xc3\xa0", vmime::charset("utf-8"))); + VASSERT_EQ( + "1", + vmime::wordEncoder::ENCODING_B64, + vmime::wordEncoder::guessBestEncoding("xxxxx\xc3\xa0\xc3\xa0", vmime::charset("utf-8")) + ); // ...else Quoted-Printable - VASSERT_EQ("2", vmime::wordEncoder::ENCODING_QP, - vmime::wordEncoder::guessBestEncoding("xxxxxx\xc3\xa0\xc3\xa0", vmime::charset("utf-8"))); + VASSERT_EQ( + "2", + vmime::wordEncoder::ENCODING_QP, + vmime::wordEncoder::guessBestEncoding("xxxxxx\xc3\xa0\xc3\xa0", vmime::charset("utf-8")) + ); } - void testEncodeQP_RFC2047() - { + void testEncodeQP_RFC2047() { + // When Quoted-Printable is used, it should be RFC-2047 QP encoding vmime::wordEncoder we( "buffer\xc3\xa0 foo_bar", vmime::charset("utf-8"), - vmime::wordEncoder::ENCODING_AUTO); + vmime::wordEncoder::ENCODING_AUTO + ); VASSERT_EQ("1", "buffer=C3=A0_foo=5Fbar", we.getNextChunk(100)); } diff --git a/tests/security/digest/md5Test.cpp b/tests/security/digest/md5Test.cpp index c7f0b521..ca6d3d45 100644 --- a/tests/security/digest/md5Test.cpp +++ b/tests/security/digest/md5Test.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -54,8 +54,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) // Test suites from RFC #1321 - void testRFC1321_1() - { + void testRFC1321_1() { + INIT_DIGEST(algo, "md5"); algo->update(""); @@ -64,8 +64,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "d41d8cd98f00b204e9800998ecf8427e", algo->getHexDigest()); } - void testRFC1321_2() - { + void testRFC1321_2() { + INIT_DIGEST(algo, "md5"); algo->update("a"); @@ -74,8 +74,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "0cc175b9c0f1b6a831c399e269772661", algo->getHexDigest()); } - void testRFC1321_3() - { + void testRFC1321_3() { + INIT_DIGEST(algo, "md5"); algo->update("abc"); @@ -84,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "900150983cd24fb0d6963f7d28e17f72", algo->getHexDigest()); } - void testRFC1321_4() - { + void testRFC1321_4() { + INIT_DIGEST(algo, "md5"); algo->update("message digest"); @@ -94,8 +94,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "f96b697d7cb7938d525a2f31aaf161d0", algo->getHexDigest()); } - void testRFC1321_5() - { + void testRFC1321_5() { + INIT_DIGEST(algo, "md5"); algo->update("abcdefghijklmnopqrstuvwxyz"); @@ -104,8 +104,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "c3fcd3d76192e4007dfb496cca67e13b", algo->getHexDigest()); } - void testRFC1321_6() - { + void testRFC1321_6() { + INIT_DIGEST(algo, "md5"); algo->update("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); @@ -114,8 +114,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "d174ab98d277d9f5a5611c2c9f419d9f", algo->getHexDigest()); } - void testRFC1321_7() - { + void testRFC1321_7() { + INIT_DIGEST(algo, "md5"); algo->update("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); @@ -124,8 +124,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "57edf4a22be3c955ac49da2e2107b67a", algo->getHexDigest()); } - void testReset() - { + void testReset() { + INIT_DIGEST(algo, "md5"); algo->update("foo"); @@ -138,8 +138,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "d41d8cd98f00b204e9800998ecf8427e", algo->getHexDigest()); // empty string } - void testUpdate1() - { + void testUpdate1() { + INIT_DIGEST(algo, "md5"); algo->update(""); @@ -148,8 +148,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("*", "d41d8cd98f00b204e9800998ecf8427e", algo->getHexDigest()); } - void testUpdate2() - { + void testUpdate2() { + INIT_DIGEST(algo, "md5"); algo->update("a"); @@ -159,8 +159,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("2", "0cc175b9c0f1b6a831c399e269772661", algo->getHexDigest()); } - void testUpdate3() - { + void testUpdate3() { + INIT_DIGEST(algo, "md5"); algo->update("ab"); @@ -170,8 +170,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("3", "900150983cd24fb0d6963f7d28e17f72", algo->getHexDigest()); } - void testUpdate4() - { + void testUpdate4() { + INIT_DIGEST(algo, "md5"); algo->update(""); @@ -183,8 +183,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("4", "f96b697d7cb7938d525a2f31aaf161d0", algo->getHexDigest()); } - void testUpdate5() - { + void testUpdate5() { + INIT_DIGEST(algo, "md5"); algo->update("abcd"); @@ -197,8 +197,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("5", "c3fcd3d76192e4007dfb496cca67e13b", algo->getHexDigest()); } - void testUpdate6() - { + void testUpdate6() { + INIT_DIGEST(algo, "md5"); algo->update("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012"); @@ -211,8 +211,8 @@ VMIME_TEST_SUITE_BEGIN(md5Test) VASSERT_EQ("6", "d174ab98d277d9f5a5611c2c9f419d9f", algo->getHexDigest()); } - void testUpdate7() - { + void testUpdate7() { + INIT_DIGEST(algo, "md5"); algo->update("12345678901234567890123456789"); @@ -226,4 +226,3 @@ VMIME_TEST_SUITE_BEGIN(md5Test) } VMIME_TEST_SUITE_END - diff --git a/tests/security/digest/sha1Test.cpp b/tests/security/digest/sha1Test.cpp index c6ce1e65..cbcd1cf0 100644 --- a/tests/security/digest/sha1Test.cpp +++ b/tests/security/digest/sha1Test.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -46,8 +46,8 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) // Test suites from FIPS PUB 180-1 // http://www.itl.nist.gov/fipspubs/fip180-1.htm - void testFIPS180_1() - { + void testFIPS180_1() { + INIT_DIGEST(algo, "sha1"); algo->update("abc"); @@ -56,8 +56,8 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) VASSERT_EQ("*", "a9993e364706816aba3e25717850c26c9cd0d89d", algo->getHexDigest()); } - void testFIPS180_2() - { + void testFIPS180_2() { + INIT_DIGEST(algo, "sha1"); algo->update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); @@ -66,14 +66,15 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) VASSERT_EQ("*", "84983e441c3bd26ebaae4aa1f95129e5e54670f1", algo->getHexDigest()); } - void testFIPS180_3() - { + void testFIPS180_3() { + INIT_DIGEST(algo, "sha1"); vmime::byte_t* buffer = new vmime::byte_t[1000000]; - for (int i = 0 ; i < 1000000 ; ++i) + for (int i = 0 ; i < 1000000 ; ++i) { buffer[i] = 'a'; + } algo->update(buffer, 1000000); algo->finalize(); @@ -83,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) VASSERT_EQ("*", "34aa973cd4c4daa4f61eeb2bdbad27316534016f", algo->getHexDigest()); } - void testReset() - { + void testReset() { + INIT_DIGEST(algo, "sha1"); algo->update("ab"); @@ -97,8 +98,8 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) VASSERT_EQ("*", "da39a3ee5e6b4b0d3255bfef95601890afd80709", algo->getHexDigest()); // empty string } - void testUpdate() - { + void testUpdate() { + INIT_DIGEST(algo, "sha1"); algo->update("a"); @@ -116,4 +117,3 @@ VMIME_TEST_SUITE_BEGIN(sha1Test) } VMIME_TEST_SUITE_END - diff --git a/tests/testRunner.cpp b/tests/testRunner.cpp index 08a06930..f1f13b25 100644 --- a/tests/testRunner.cpp +++ b/tests/testRunner.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -45,19 +45,19 @@ #include "vmime/platforms/posix/posixHandler.hpp" -class Clock -{ +class Clock { + public: - void reset() - { + void reset() { + struct timezone tz; gettimeofday(&m_start, &tz); } - double getDuration() const - { + double getDuration() const { + struct timeval tv; struct timezone tz; @@ -73,18 +73,19 @@ private: }; -class XmlTestListener : public CppUnit::TestListener -{ +class XmlTestListener : public CppUnit::TestListener { + public: XmlTestListener() - : m_doc("utf-8"), m_testElt(NULL) - { + : m_doc("utf-8"), + m_testElt(NULL) { + m_doc.setRootElement(new CppUnit::XmlElement("TestRun")); } - void startTest(CppUnit::Test* test) - { + void startTest(CppUnit::Test* test) { + m_testElt = new CppUnit::XmlElement("Test"); m_suiteElt.back()->addElement(m_testElt); @@ -93,16 +94,17 @@ public: m_chrono.reset(); } - void addFailure(const CppUnit::TestFailure& failure) - { + void addFailure(const CppUnit::TestFailure& failure) { + CppUnit::XmlElement* failElt = new CppUnit::XmlElement("Failure"); m_testElt->addElement(failElt); - failElt->addElement(new CppUnit::XmlElement("FailureType", - failure.isError() ? "Error" : "Assertion")); + failElt->addElement( + new CppUnit::XmlElement("FailureType", failure.isError() ? "Error" : "Assertion") + ); + + if (failure.sourceLine().isValid()) { - if (failure.sourceLine().isValid()) - { CppUnit::XmlElement* locElt = new CppUnit::XmlElement("Location"); failElt->addElement(locElt); @@ -116,8 +118,8 @@ public: exElt->addElement(new CppUnit::XmlElement("Message", failure.thrownException()->what())); } - void endTest(CppUnit::Test* /* test */) - { + void endTest(CppUnit::Test* /* test */) { + std::ostringstream ossTime; ossTime << (m_chrono.getDuration() * 1000.0); @@ -126,39 +128,42 @@ public: m_testElt = NULL; } - void startSuite(CppUnit::Test* suite) - { - if (suite->getName() == "All Tests") + void startSuite(CppUnit::Test* suite) { + + if (suite->getName() == "All Tests") { return; + } CppUnit::XmlElement* suiteElt = new CppUnit::XmlElement("Suite"); - if (m_suiteElt.size() == 0) + if (m_suiteElt.size() == 0) { m_doc.rootElement().addElement(suiteElt); - else + } else { m_suiteElt.back()->addElement(suiteElt); + } m_suiteElt.push_back(suiteElt); suiteElt->addElement(new CppUnit::XmlElement("Name", suite->getName())); } - void endSuite(CppUnit::Test* /* suite */) - { - if (m_suiteElt.size()) + void endSuite(CppUnit::Test* /* suite */) { + + if (m_suiteElt.size()) { m_suiteElt.pop_back(); + } } - void startTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */) - { + void startTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */) { + } - void endTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */) - { + void endTestRun(CppUnit::Test* /* test */, CppUnit::TestResult* /* eventManager */) { + } - void output(std::ostream& os) - { + void output(std::ostream& os) { + os << m_doc.toString(); } @@ -175,43 +180,46 @@ private: // see testUtils.hpp -std::vector & getTestModules() -{ +std::vector & getTestModules() { + static std::vector allModules; return allModules; } -void registerTestModule(const char* name_) -{ +void registerTestModule(const char* name_) { + std::vector & testModules = getTestModules(); std::string name(name_); - if (std::find(testModules.begin(), testModules.end(), name) == testModules.end()) + if (std::find(testModules.begin(), testModules.end(), name) == testModules.end()) { testModules.push_back(name); + } } -const std::string getNormalizedPath(const std::string& path) -{ +const std::string getNormalizedPath(const std::string& path) { + std::string res = path; - for (std::size_t i = 0, n = res.length() ; i < n ; ++i) - { - if (res[i] == '\\') + for (std::size_t 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 getFileNameFromPath(const std::string& path) { + const std::size_t pos = path.find_last_of('/'); - if (pos == std::string::npos) + if (pos == std::string::npos) { return ""; + } return path.substr(pos + 1); } @@ -220,8 +228,8 @@ const std::string getFileNameFromPath(const std::string& path) static char g_moduleNameBuffer[2048]; -const char* getTestModuleNameFromSourceFile(const char *path_) -{ +const char* getTestModuleNameFromSourceFile(const char *path_) { + static const std::string testRunnerPath(getNormalizedPath(__FILE__)); static const std::string testRunnerFileName(getFileNameFromPath(testRunnerPath)); @@ -244,29 +252,31 @@ const char* getTestModuleNameFromSourceFile(const char *path_) } -int main(int argc, char* argv[]) -{ +int main(int argc, char* argv[]) { + // Parse arguments bool xmlOutput = false; - for (int c = 1 ; c < argc ; ++c) - { + for (int c = 1 ; c < argc ; ++c) { + const std::string arg = argv[c]; - if (arg == "--xml") + if (arg == "--xml") { xmlOutput = true; + } } // Run the tests - if (xmlOutput) - { + if (xmlOutput) { + // Get the test suites from the registry and add them to the list of tests to run CppUnit::TestRunner runner; - for (unsigned int i = 0 ; i < getTestModules().size() ; ++i) - { - runner.addTest(CppUnit::TestFactoryRegistry:: - getRegistry(getTestModules()[i]).makeTest()); + for (unsigned int i = 0 ; i < getTestModules().size() ; ++i) { + + runner.addTest( + CppUnit::TestFactoryRegistry::getRegistry(getTestModules()[i]).makeTest() + ); } XmlTestListener xmlListener; @@ -283,9 +293,9 @@ int main(int argc, char* argv[]) // Return error code 1 if a test failed return result.wasSuccessful() ? 0 : 1; - } - else - { + + } else { + // Get the top level suite from the registry CppUnit::TextUi::TestRunner runner; runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); @@ -293,4 +303,3 @@ int main(int argc, char* argv[]) return runner.run() ? 0 : 1; } } - diff --git a/tests/testUtils.cpp b/tests/testUtils.cpp index 6e31d93f..ae755474 100644 --- a/tests/testUtils.cpp +++ b/tests/testUtils.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -36,8 +36,8 @@ // testSocket -void testSocket::connect(const vmime::string& address, const vmime::port_t port) -{ +void testSocket::connect(const vmime::string& address, const vmime::port_t port) { + m_address = address; m_port = port; m_connected = true; @@ -46,96 +46,96 @@ void testSocket::connect(const vmime::string& address, const vmime::port_t port) } -void testSocket::disconnect() -{ +void testSocket::disconnect() { + m_address.clear(); m_port = 0; m_connected = false; } -bool testSocket::isConnected() const -{ +bool testSocket::isConnected() const { + return m_connected; } -vmime::size_t testSocket::getBlockSize() const -{ +vmime::size_t testSocket::getBlockSize() const { + return 16384; } -unsigned int testSocket::getStatus() const -{ +unsigned int testSocket::getStatus() const { + return 0; } -const vmime::string testSocket::getPeerName() const -{ +const vmime::string testSocket::getPeerName() const { + return "test.vmime.org"; } -const vmime::string testSocket::getPeerAddress() const -{ +const vmime::string testSocket::getPeerAddress() const { + return "127.0.0.1"; } -vmime::shared_ptr testSocket::getTimeoutHandler() -{ +vmime::shared_ptr testSocket::getTimeoutHandler() { + return vmime::null; } -void testSocket::setTracer(const vmime::shared_ptr & /* tracer */) -{ +void testSocket::setTracer(const vmime::shared_ptr & /* tracer */) { + } -vmime::shared_ptr testSocket::getTracer() -{ +vmime::shared_ptr testSocket::getTracer() { + return vmime::null; } -bool testSocket::waitForRead(const int /* msecs */) -{ +bool testSocket::waitForRead(const int /* msecs */) { + return true; } -bool testSocket::waitForWrite(const int /* msecs */) -{ +bool testSocket::waitForWrite(const int /* msecs */) { + return true; } -void testSocket::receive(vmime::string& buffer) -{ +void testSocket::receive(vmime::string& buffer) { + buffer = m_inBuffer; m_inBuffer.clear(); } -void testSocket::send(const vmime::string& buffer) -{ +void testSocket::send(const vmime::string& buffer) { + m_outBuffer += buffer; onDataReceived(); } -void testSocket::send(const char* str) -{ +void testSocket::send(const char* str) { + sendRaw(reinterpret_cast (str), strlen(str)); } -vmime::size_t testSocket::receiveRaw(vmime::byte_t* buffer, const size_t count) -{ +vmime::size_t testSocket::receiveRaw(vmime::byte_t* buffer, const size_t count) { + const size_t n = std::min(count, static_cast (m_inBuffer.size())); std::copy(m_inBuffer.begin(), m_inBuffer.begin() + n, buffer); @@ -145,21 +145,21 @@ vmime::size_t testSocket::receiveRaw(vmime::byte_t* buffer, const size_t count) } -void testSocket::sendRaw(const vmime::byte_t* buffer, const size_t count) -{ +void testSocket::sendRaw(const vmime::byte_t* buffer, const size_t count) { + send(vmime::utility::stringUtils::makeStringFromBytes(buffer, count)); } -vmime::size_t testSocket::sendRawNonBlocking(const vmime::byte_t* buffer, const size_t count) -{ +vmime::size_t testSocket::sendRawNonBlocking(const vmime::byte_t* buffer, const size_t count) { + sendRaw(buffer, count); return count; } -void testSocket::localSend(const vmime::string& buffer) -{ +void testSocket::localSend(const vmime::string& buffer) { + m_inBuffer += buffer; #if DEBUG_SOCKET_IN_OUT @@ -169,23 +169,24 @@ void testSocket::localSend(const vmime::string& buffer) } -void testSocket::localReceive(vmime::string& buffer) -{ +void testSocket::localReceive(vmime::string& buffer) { + buffer = m_outBuffer; m_outBuffer.clear(); } -bool testSocket::localReceiveLine(vmime::string& line) -{ +bool testSocket::localReceiveLine(vmime::string& line) { + vmime::size_t eol; - if ((eol = m_outBuffer.find('\n')) != vmime::string::npos) - { + if ((eol = m_outBuffer.find('\n')) != vmime::string::npos) { + line = vmime::string(m_outBuffer.begin(), m_outBuffer.begin() + eol); - if (!line.empty() && line[line.length() - 1] == '\r') + if (!line.empty() && line[line.length() - 1] == '\r') { line.erase(line.end() - 1, line.end()); + } m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + eol + 1); @@ -196,14 +197,15 @@ bool testSocket::localReceiveLine(vmime::string& line) } -vmime::size_t testSocket::localReceiveRaw(vmime::byte_t* buffer, const size_t count) -{ +vmime::size_t testSocket::localReceiveRaw(vmime::byte_t* buffer, const size_t count) { + const size_t received = std::min(count, static_cast (m_outBuffer.size())); - if (received != 0) - { - if (buffer != NULL) + if (received != 0) { + + if (buffer) { std::copy(m_outBuffer.begin(), m_outBuffer.begin() + received, buffer); + } m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + received); } @@ -212,22 +214,22 @@ vmime::size_t testSocket::localReceiveRaw(vmime::byte_t* buffer, const size_t co } -void testSocket::onDataReceived() -{ +void testSocket::onDataReceived() { + // Override } -void testSocket::onConnected() -{ +void testSocket::onConnected() { + // Override } // lineBasedTestSocket -void lineBasedTestSocket::onDataReceived() -{ +void lineBasedTestSocket::onDataReceived() { + vmime::string chunk; localReceive(chunk); @@ -235,12 +237,13 @@ void lineBasedTestSocket::onDataReceived() vmime::size_t eol; - while ((eol = m_buffer.find('\n')) != vmime::string::npos) - { + while ((eol = m_buffer.find('\n')) != vmime::string::npos) { + vmime::string line(std::string(m_buffer.begin(), m_buffer.begin() + eol)); - if (!line.empty() && line[line.length() - 1] == '\r') + if (!line.empty() && line[line.length() - 1] == '\r') { line.erase(line.end() - 1, line.end()); + } #if DEBUG_SOCKET_IN_OUT std::cout << "< " << vmime::utility::stringUtils::trim(line) << std::endl; @@ -250,20 +253,22 @@ void lineBasedTestSocket::onDataReceived() m_buffer.erase(m_buffer.begin(), m_buffer.begin() + eol + 1); } - while (!m_lines.empty()) + while (!m_lines.empty()) { processCommand(); + } } -const vmime::string lineBasedTestSocket::getNextLine() -{ +const vmime::string lineBasedTestSocket::getNextLine() { + const vmime::string line = m_lines.front(); m_lines.erase(m_lines.begin(), m_lines.begin() + 1); return line; } -bool lineBasedTestSocket::haveMoreLines() const -{ + +bool lineBasedTestSocket::haveMoreLines() const { + return !m_lines.empty(); } @@ -271,47 +276,48 @@ bool lineBasedTestSocket::haveMoreLines() const // testTimeoutHandler testTimeoutHandler::testTimeoutHandler(const unsigned long delay) - : m_delay(delay), m_start(0) -{ + : m_delay(delay), + m_start(0) { + } -bool testTimeoutHandler::isTimeOut() -{ +bool testTimeoutHandler::isTimeOut() { + return (vmime::platform::getHandler()->getUnixTime() - m_start) >= m_delay; } -void testTimeoutHandler::resetTimeOut() -{ +void testTimeoutHandler::resetTimeOut() { + m_start = vmime::platform::getHandler()->getUnixTime(); } -bool testTimeoutHandler::handleTimeOut() -{ +bool testTimeoutHandler::handleTimeOut() { + return false; } // testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory -vmime::shared_ptr testTimeoutHandlerFactory::create() -{ +vmime::shared_ptr testTimeoutHandlerFactory::create() { + return vmime::make_shared (); } // Exception helper -std::ostream& operator<<(std::ostream& os, const vmime::exception& e) -{ +std::ostream& operator<<(std::ostream& os, const vmime::exception& e) { + os << "* vmime::exceptions::" << e.name() << std::endl; os << " what = " << e.what() << std::endl; // More information for special exceptions - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::command_error& cee = dynamic_cast (e); @@ -319,32 +325,32 @@ std::ostream& operator<<(std::ostream& os, const vmime::exception& e) os << " response = " << cee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::invalid_response& ir = dynamic_cast (e); os << " response = " << ir.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::connection_greeting_error& cgee = dynamic_cast (e); os << " response = " << cgee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::authentication_error& aee = dynamic_cast (e); os << " response = " << aee.response() << std::endl; } - if (dynamic_cast (&e)) - { + if (dynamic_cast (&e)) { + const vmime::exceptions::filesystem_exception& fse = dynamic_cast (e); @@ -352,29 +358,29 @@ std::ostream& operator<<(std::ostream& os, const vmime::exception& e) getFileSystemFactory()->pathToString(fse.path()) << std::endl; } - if (e.other() != NULL) + if (e.other()) { os << *e.other(); + } return os; } -const vmime::string toHex(const vmime::string str) -{ +const vmime::string toHex(const vmime::string str) { + static const char hexChars[] = "0123456789abcdef"; vmime::string res = "\n"; - for (size_t i = 0 ; i < str.length() ; i += 16) - { - size_t r = std::min - (static_cast (16), str.length() - i); + for (size_t i = 0 ; i < str.length() ; i += 16) { + + size_t r = std::min(static_cast (16), str.length() - i); vmime::string hex; vmime::string chr; - for (size_t j = 0 ; j < r ; ++j) - { + for (size_t j = 0 ; j < r ; ++j) { + const unsigned char c = str[i + j]; hex += hexChars[c / 16]; @@ -387,8 +393,9 @@ const vmime::string toHex(const vmime::string str) chr += '.'; } - for (size_t j = r ; j < 16 ; ++j) + for (size_t j = r ; j < 16 ; ++j) { hex += " "; + } res += hex + " " + chr + "\n"; } diff --git a/tests/testUtils.hpp b/tests/testUtils.hpp index d17c38b2..e6bf1eee 100644 --- a/tests/testUtils.hpp +++ b/tests/testUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -88,123 +88,134 @@ #define VMIME_TEST(name) CPPUNIT_TEST(name); -namespace CppUnit -{ +namespace CppUnit { + // Work-around for comparing 'std::string' against 'char*' - inline void assertEquals(const char* expected, const std::string actual, - SourceLine sourceLine, const std::string &message) - { + inline void assertEquals( + const char* expected, + const std::string actual, + SourceLine sourceLine, + const std::string &message + ) { + assertEquals(std::string(expected), actual, sourceLine, message); } template - void assertEquals(const X expected, const Y actual, - SourceLine sourceLine, const std::string &message) - { + void assertEquals( + const X expected, + const Y actual, + SourceLine sourceLine, + const std::string &message + ) { + assertEquals(static_cast (expected), actual, sourceLine, message); } } -namespace std -{ +namespace std { -inline std::ostream& operator<<(std::ostream& os, const vmime::charset& ch) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::charset& ch) { + os << "[charset: " << ch.getName() << "]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::word& w) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::word& w) { + os << "[word: charset=" << w.getCharset().getName() << ", buffer=" << w.getBuffer(); - if (!w.getLanguage().empty()) + if (!w.getLanguage().empty()) { os << ", lang=" << w.getLanguage(); + } os << "]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::text& txt) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::text& txt) { + os << "[text: ["; - for (size_t i = 0 ; i < txt.getWordCount() ; ++i) - { + for (size_t i = 0 ; i < txt.getWordCount() ; ++i) { + const vmime::word& w = *txt.getWordAt(i); - if (i != 0) + if (i != 0) { os << ","; + } os << w; } os << "]]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::emailAddress& email) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::emailAddress& email) { + os << email.generate(); - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox) { + os << "[mailbox: name=" << mbox.getName() << ", email=" << mbox.getEmail() << "]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::mailboxGroup& group) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::mailboxGroup& group) { + os << "[mailbox-group: name=" << group.getName() << ", list=["; - for (size_t i = 0 ; i < group.getMailboxCount() ; ++i) - { - if (i != 0) + for (size_t i = 0 ; i < group.getMailboxCount() ; ++i) { + + if (i != 0) { os << ","; + } os << *group.getMailboxAt(i); } os << "]]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::addressList& list) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::addressList& list) { + os << "[address-list: ["; - for (size_t i = 0 ; i < list.getAddressCount() ; ++i) - { + for (size_t i = 0 ; i < list.getAddressCount() ; ++i) { + const vmime::address& addr = *list.getAddressAt(i); - if (i != 0) + if (i != 0) { os << ","; + } + + if (addr.isGroup()) { - if (addr.isGroup()) - { const vmime::mailboxGroup& group = dynamic_cast (addr); os << group; - } - else - { + + } else { + const vmime::mailbox& mbox = dynamic_cast (addr); @@ -214,25 +225,25 @@ inline std::ostream& operator<<(std::ostream& os, const vmime::addressList& list os << "]]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::datetime& d) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::datetime& d) { + os << "[datetime: " << d.getYear() << "/" << d.getMonth() << "/" << d.getDay(); os << " " << d.getHour() << ":" << d.getMinute() << ":" << d.getSecond(); os << " #" << d.getZone() << "]"; - return (os); + return os; } -inline std::ostream& operator<<(std::ostream& os, const vmime::encoding& enc) -{ +inline std::ostream& operator<<(std::ostream& os, const vmime::encoding& enc) { + os << enc.generate(); - return (os); + return os; } @@ -246,8 +257,8 @@ inline std::ostream& operator<<(std::ostream& os, const vmime::encoding& enc) // and send(). Server reads incoming data with localReceive() and sends data // to client with localSend(). -class testSocket : public vmime::net::socket -{ +class testSocket : public vmime::net::socket { + public: void connect(const vmime::string& address, const vmime::port_t port); @@ -327,24 +338,26 @@ private: template -class testSocketFactory : public vmime::net::socketFactory -{ +class testSocketFactory : public vmime::net::socketFactory { + public: - vmime::shared_ptr create() - { + vmime::shared_ptr create() { + return vmime::make_shared (); } - vmime::shared_ptr create(const vmime::shared_ptr & /* th */) - { + vmime::shared_ptr create( + const vmime::shared_ptr & /* th */ + ) { + return vmime::make_shared (); } }; -class lineBasedTestSocket : public testSocket -{ +class lineBasedTestSocket : public testSocket { + public: void onDataReceived(); @@ -361,8 +374,8 @@ private: }; -class testTimeoutHandler : public vmime::net::timeoutHandler -{ +class testTimeoutHandler : public vmime::net::timeoutHandler { + public: testTimeoutHandler(const unsigned long delay = 3); @@ -378,8 +391,8 @@ private: }; -class testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory -{ +class testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory { + public: vmime::shared_ptr create(); diff --git a/tests/utility/datetimeUtilsTest.cpp b/tests/utility/datetimeUtilsTest.cpp index 1e21c5f9..77ce2425 100644 --- a/tests/utility/datetimeUtilsTest.cpp +++ b/tests/utility/datetimeUtilsTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,8 +43,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) typedef vmime::utility::datetimeUtils datetimeUtils; - void testIsLeapYear() - { + void testIsLeapYear() { + VASSERT_EQ("1", false, datetimeUtils::isLeapYear(1999)); VASSERT_EQ("2", false, datetimeUtils::isLeapYear(1800)); VASSERT_EQ("3", false, datetimeUtils::isLeapYear(1900)); @@ -55,8 +55,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("7", true, datetimeUtils::isLeapYear(2000)); } - void testGetDaysInMonth() - { + void testGetDaysInMonth() { + VASSERT_EQ("1", 31, datetimeUtils::getDaysInMonth(2006, 1)); VASSERT_EQ("2", 28, datetimeUtils::getDaysInMonth(2006, 2)); VASSERT_EQ("3", 31, datetimeUtils::getDaysInMonth(2006, 3)); @@ -71,8 +71,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("12", 31, datetimeUtils::getDaysInMonth(2006, 12)); } - void testGetDaysInMonthLeapYear() - { + void testGetDaysInMonthLeapYear() { + VASSERT_EQ("1", 31, datetimeUtils::getDaysInMonth(2004, 1)); VASSERT_EQ("2", 29, datetimeUtils::getDaysInMonth(2004, 2)); VASSERT_EQ("3", 31, datetimeUtils::getDaysInMonth(2004, 3)); @@ -87,13 +87,11 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("12", 31, datetimeUtils::getDaysInMonth(2004, 12)); } - void testToUniversalTime() - { - const vmime::datetime local - (2005, 12, 2, 12, 34, 56, -789); + void testToUniversalTime() { - const vmime::datetime gmt = - datetimeUtils::toUniversalTime(local); + const vmime::datetime local(2005, 12, 2, 12, 34, 56, -789); + + const vmime::datetime gmt = datetimeUtils::toUniversalTime(local); // 789 is 13 hours, 9 minutes later VASSERT_EQ("1", 2005, gmt.getYear()); @@ -105,13 +103,11 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("7", 0, gmt.getZone()); } - void testToLocalTime() - { - const vmime::datetime date - (2005, 12, 2, 12, 34, 56, -120); // GMT-2 + void testToLocalTime() { - const vmime::datetime local = - datetimeUtils::toLocalTime(date, 120); // GMT+2 + const vmime::datetime date(2005, 12, 2, 12, 34, 56, -120); // GMT-2 + + const vmime::datetime local = datetimeUtils::toLocalTime(date, 120); // GMT+2 VASSERT_EQ("1", 2005, local.getYear()); VASSERT_EQ("2", 12, local.getMonth()); @@ -122,8 +118,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("7", 120, local.getZone()); } - void testGetDayOfWeek() - { + void testGetDayOfWeek() { + VASSERT_EQ("1", vmime::datetime::WEDNESDAY, datetimeUtils::getDayOfWeek(1969, 12, 31)); VASSERT_EQ("2", vmime::datetime::FRIDAY, datetimeUtils::getDayOfWeek(1976, 4, 9)); VASSERT_EQ("3", vmime::datetime::TUESDAY, datetimeUtils::getDayOfWeek(1987, 6, 23)); @@ -135,8 +131,8 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) VASSERT_EQ("9", vmime::datetime::FRIDAY, datetimeUtils::getDayOfWeek(2027, 3, 12)); } - void testGetWeekOfYear() - { + void testGetWeekOfYear() { + VASSERT_EQ("1.1", 52, datetimeUtils::getWeekOfYear(2003, 12, 27)); VASSERT_EQ("1.2", 52, datetimeUtils::getWeekOfYear(2003, 12, 28)); VASSERT_EQ("1.3", 1, datetimeUtils::getWeekOfYear(2003, 12, 29, true)); @@ -159,4 +155,3 @@ VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/encoder/b64EncoderTest.cpp b/tests/utility/encoder/b64EncoderTest.cpp index fa6fd766..36fa61ac 100644 --- a/tests/utility/encoder/b64EncoderTest.cpp +++ b/tests/utility/encoder/b64EncoderTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,10 +33,10 @@ VMIME_TEST_SUITE_BEGIN(b64EncoderTest) VMIME_TEST_LIST_END - void testBase64() - { - static const vmime::string testSuites[] = - { + void testBase64() { + + static const vmime::string testSuites[] = { + // Test 1 "", @@ -96,8 +96,8 @@ VMIME_TEST_SUITE_BEGIN(b64EncoderTest) }; - for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i) - { + 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]; @@ -111,25 +111,36 @@ VMIME_TEST_SUITE_BEGIN(b64EncoderTest) VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded)); // Multiple and successive encoding/decoding - VASSERT_EQ(oss.str() + "multiple1", decoded, + VASSERT_EQ( + oss.str() + "multiple1", + decoded, decode("base64", - encode("base64", decoded))); + encode("base64", decoded)) + ); - VASSERT_EQ(oss.str() + "multiple2", decoded, + VASSERT_EQ( + oss.str() + "multiple2", + decoded, decode("base64", decode("base64", encode("base64", - encode("base64", decoded))))); + encode("base64", decoded)))) + ); - VASSERT_EQ(oss.str() + "multiple3", decoded, + VASSERT_EQ( + oss.str() + "multiple3", + decoded, decode("base64", decode("base64", decode("base64", encode("base64", encode("base64", - encode("base64", decoded))))))); + encode("base64", decoded)))))) + ); - VASSERT_EQ(oss.str() + "multiple4", decoded, + VASSERT_EQ( + oss.str() + "multiple4", + decoded, decode("base64", decode("base64", decode("base64", @@ -137,17 +148,21 @@ VMIME_TEST_SUITE_BEGIN(b64EncoderTest) encode("base64", encode("base64", encode("base64", - encode("base64", decoded))))))))); + encode("base64", decoded)))))))) + ); - VASSERT(oss.str() + "encoded size", + VASSERT( + oss.str() + "encoded size", getEncoder("base64")->getEncodedSize(decoded.length()) - >= encode("base64", decoded).length()); + >= encode("base64", decoded).length() + ); - VASSERT(oss.str() + "decoded size", + VASSERT( + oss.str() + "decoded size", getEncoder("base64")->getDecodedSize(encoded.length()) - >= decode("base64", encoded).length()); + >= decode("base64", encoded).length() + ); } } VMIME_TEST_SUITE_END - diff --git a/tests/utility/encoder/encoderFactoryTest.cpp b/tests/utility/encoder/encoderFactoryTest.cpp index ce50dc6a..916706c9 100644 --- a/tests/utility/encoder/encoderFactoryTest.cpp +++ b/tests/utility/encoder/encoderFactoryTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ VMIME_TEST_SUITE_BEGIN(encoderFactoryTest) VMIME_TEST_LIST_END - void testNoDefaultEncoder() - { + void testNoDefaultEncoder() { + vmime::shared_ptr ef = vmime::utility::encoder::encoderFactory::getInstance(); @@ -47,8 +47,8 @@ VMIME_TEST_SUITE_BEGIN(encoderFactoryTest) ); } - void testDefaultEncoder() - { + void testDefaultEncoder() { + vmime::shared_ptr ef = vmime::utility::encoder::encoderFactory::getInstance(); diff --git a/tests/utility/encoder/encoderTestUtils.hpp b/tests/utility/encoder/encoderTestUtils.hpp index d74c4709..cc1141c7 100644 --- a/tests/utility/encoder/encoderTestUtils.hpp +++ b/tests/utility/encoder/encoderTestUtils.hpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -23,25 +23,32 @@ // Helper function to obtain an encoder given its name -static vmime::shared_ptr getEncoder(const vmime::string& name, - int maxLineLength = 0, const vmime::propertySet props = vmime::propertySet()) -{ +static vmime::shared_ptr getEncoder( + const vmime::string& name, + int maxLineLength = 0, + const vmime::propertySet props = vmime::propertySet() +) { + vmime::shared_ptr enc = vmime::utility::encoder::encoderFactory::getInstance()->create(name); enc->getProperties() = props; - if (maxLineLength != 0) + if (maxLineLength != 0) { enc->getProperties()["maxlinelength"] = maxLineLength; + } return enc; } // 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()) -{ +static const vmime::string encode( + const vmime::string& name, const vmime::string& in, + int maxLineLength = 0, + const vmime::propertySet props = vmime::propertySet() +) { + vmime::shared_ptr enc = getEncoder(name, maxLineLength, props); vmime::utility::inputStreamStringAdapter vin(in); @@ -56,8 +63,12 @@ static const vmime::string encode(const vmime::string& name, const vmime::string // Decoding helper function -static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0) -{ +static const vmime::string decode( + const vmime::string& name, + const vmime::string& in, + int maxLineLength = 0 +) { + vmime::shared_ptr enc = getEncoder(name, maxLineLength); vmime::utility::inputStreamStringAdapter vin(in); diff --git a/tests/utility/encoder/qpEncoderTest.cpp b/tests/utility/encoder/qpEncoderTest.cpp index e7d1bcd2..e4769475 100644 --- a/tests/utility/encoder/qpEncoderTest.cpp +++ b/tests/utility/encoder/qpEncoderTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -38,10 +38,10 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) VMIME_TEST_LIST_END - void testQuotedPrintable() - { - static const vmime::string testSuites[] = - { + void testQuotedPrintable() { + + static const vmime::string testSuites[] = { + // Test 1 "", @@ -94,8 +94,8 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) }; - for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i) - { + 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]; @@ -109,25 +109,36 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) VASSERT_EQ(oss.str() + "decoding", decoded, decode("quoted-printable", encoded, 74)); // Multiple and successive encoding/decoding - VASSERT_EQ(oss.str() + "multiple1", decoded, + VASSERT_EQ( + oss.str() + "multiple1", + decoded, decode("quoted-printable", - encode("quoted-printable", decoded))); + encode("quoted-printable", decoded)) + ); - VASSERT_EQ(oss.str() + "multiple2", decoded, + VASSERT_EQ( + oss.str() + "multiple2", + decoded, decode("quoted-printable", decode("quoted-printable", encode("quoted-printable", - encode("quoted-printable", decoded))))); + encode("quoted-printable", decoded)))) + ); - VASSERT_EQ(oss.str() + "multiple3", decoded, + VASSERT_EQ( + oss.str() + "multiple3", + decoded, decode("quoted-printable", decode("quoted-printable", decode("quoted-printable", encode("quoted-printable", encode("quoted-printable", - encode("quoted-printable", decoded))))))); + encode("quoted-printable", decoded)))))) + ); - VASSERT_EQ(oss.str() + "multiple4", decoded, + VASSERT_EQ( + oss.str() + "multiple4", + decoded, decode("quoted-printable", decode("quoted-printable", decode("quoted-printable", @@ -135,38 +146,50 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) encode("quoted-printable", encode("quoted-printable", encode("quoted-printable", - encode("quoted-printable", decoded))))))))); + encode("quoted-printable", decoded)))))))) + ); - VASSERT(oss.str() + "encoded size", + VASSERT( + oss.str() + "encoded size", getEncoder("quoted-printable")->getEncodedSize(decoded.length()) - >= encode("quoted-printable", decoded).length()); + >= encode("quoted-printable", decoded).length() + ); - VASSERT(oss.str() + "decoded size", + VASSERT( + oss.str() + "decoded size", getEncoder("quoted-printable")->getDecodedSize(encoded.length()) - >= decode("quoted-printable", encoded).length()); + >= decode("quoted-printable", encoded).length() + ); } } /** Tests Soft Line Breaks (RFC-2047/6.7(5). */ - void testQuotedPrintable_SoftLineBreaks() - { - VASSERT_EQ("1", "Now's the time=\r\n" - " for all folk =\r\n" - "to come to the=\r\n" - " aid of their =\r\n" - "country.", - encode("quoted-printable", "Now's the time for all folk " - "to come to the aid of their country.", 15)); + void testQuotedPrintable_SoftLineBreaks() { + + VASSERT_EQ( + "1", + "Now's the time=\r\n" + " for all folk =\r\n" + "to come to the=\r\n" + " aid of their =\r\n" + "country.", + encode( + "quoted-printable", + "Now's the time for all folk " + "to come to the aid of their country.", + 15 + ) + ); } - void testQuotedPrintable_HardLineBreakEncode() - { + void testQuotedPrintable_HardLineBreakEncode() { + const std::string data = "If you believe that truth=beauty," " then surely mathematics\r\nis the most" " beautiful branch of philosophy."; - const std::string expected = + const std::string expected = "If you believe that truth=3Dbeauty=\r\n" ", then surely mathematics\r\n" "is the most beautiful branch of ph=\r\n" @@ -178,14 +201,14 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) VASSERT_EQ("1", expected, encode("quoted-printable", data, 35, encProps)); } - void testQuotedPrintable_HardLineBreakDecode() - { + void testQuotedPrintable_HardLineBreakDecode() { + const std::string expected = "If you believe that truth=beauty," " then surely mathematics\r\nis the most" " beautiful branch of philosophy."; - const std::string data = + const std::string data = "If you believe that truth=3Dbeauty=\r\n" ", then surely mathematics\r\n" "is the most beautiful branch of ph=\r\n" @@ -197,23 +220,29 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) /** In text mode, ensure line breaks in QP-encoded text are represented * by a CRLF sequence, as per RFC-2047/6.7(4). */ - void testQuotedPrintable_CRLF() - { + void testQuotedPrintable_CRLF() { + vmime::propertySet encProps; // in "text" mode encProps["text"] = true; - VASSERT_EQ("text", "line1\r\nline2", - encode("quoted-printable", "line1\r\nline2", 80, encProps)); + VASSERT_EQ( + "text", + "line1\r\nline2", + encode("quoted-printable", "line1\r\nline2", 80, encProps) + ); // in "binary" mode encProps["text"] = false; - VASSERT_EQ("binary", "line1=0D=0Aline2", - encode("quoted-printable", "line1\r\nline2", 80, encProps)); + VASSERT_EQ( + "binary", + "line1=0D=0Aline2", + encode("quoted-printable", "line1\r\nline2", 80, encProps) + ); } - void testQuotedPrintable_RFC2047() - { + void testQuotedPrintable_RFC2047() { + /* * The RFC (http://tools.ietf.org/html/rfc2047#section-5) says: * @@ -243,6 +272,4 @@ VMIME_TEST_SUITE_BEGIN(qpEncoderTest) VASSERT_EQ("especials.12", "=22", encode("quoted-printable", "\"", 10, encProps)); } - // TODO: UUEncode - VMIME_TEST_SUITE_END diff --git a/tests/utility/filteredStreamTest.cpp b/tests/utility/filteredStreamTest.cpp index cedfab2a..ff3fb6a3 100644 --- a/tests/utility/filteredStreamTest.cpp +++ b/tests/utility/filteredStreamTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) VMIME_TEST_LIST_END - class chunkInputStream : public vmime::utility::inputStream - { + class chunkInputStream : public vmime::utility::inputStream { + private: std::vector m_chunks; @@ -57,10 +57,11 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) bool eof() const { return (m_index >= m_chunks.size()); } void reset() { m_index = 0; } - vmime::size_t read(vmime::byte_t* const data, const vmime::size_t /* count */) - { - if (eof()) + vmime::size_t read(vmime::byte_t* const data, const vmime::size_t /* count */) { + + if (eof()) { return 0; + } const std::string chunk = m_chunks[m_index]; @@ -73,37 +74,41 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) return chunk.length(); } - vmime::size_t skip(const vmime::size_t /* count */) - { + vmime::size_t skip(const vmime::size_t /* count */) { + // Not supported return 0; } }; - const std::string readWhole(vmime::utility::inputStream& is) - { + const std::string readWhole(vmime::utility::inputStream& is) { + vmime::byte_t buffer[256]; std::string whole; - while (!is.eof()) - { + while (!is.eof()) { + const vmime::size_t read = is.read(buffer, sizeof(buffer)); whole += vmime::utility::stringUtils::makeStringFromBytes(buffer, read); } - return (whole); + return whole; } // dotFilteredInputStream - void testDotFilteredInputStreamHelper - (const std::string& number, const std::string& expected, - const std::string& c1, const std::string& c2 = "", - const std::string& c3 = "", const std::string& c4 = "") - { + void testDotFilteredInputStreamHelper( + const std::string& number, + const std::string& expected, + const std::string& c1, + const std::string& c2 = "", + const std::string& c3 = "", + const std::string& c4 = "" + ) { + chunkInputStream cis; cis.addChunk(c1); if (!c2.empty()) cis.addChunk(c2); @@ -120,8 +125,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) VASSERT_EQ(number, expected, oss.str()); } - void testDotFilteredInputStream() - { + void testDotFilteredInputStream() { + testDotFilteredInputStreamHelper("1", "foo\n.bar", "foo\n..bar"); testDotFilteredInputStreamHelper("2", "foo\n.bar", "foo\n", "..bar"); testDotFilteredInputStreamHelper("3", "foo\n.bar", "foo\n.", ".bar"); @@ -140,11 +145,15 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) // CRLFToLFFilteredOutputStream template - void testFilteredOutputStreamHelper - (const std::string& number, const std::string& expected, - const std::string& c1, const std::string& c2 = "", - const std::string& c3 = "", const std::string& c4 = "") - { + void testFilteredOutputStreamHelper( + const std::string& number, + const std::string& expected, + const std::string& c1, + const std::string& c2 = "", + const std::string& c3 = "", + const std::string& c4 = "" + ) { + std::ostringstream oss; vmime::utility::outputStreamAdapter os(oss); @@ -158,8 +167,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) VASSERT_EQ(number, expected, oss.str()); } - void testDotFilteredOutputStream() - { + void testDotFilteredOutputStream() { + typedef vmime::utility::dotFilteredOutputStream FILTER; testFilteredOutputStreamHelper("1", "foo\n..bar", "foo\n.bar"); @@ -177,8 +186,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) testFilteredOutputStreamHelper("11", "this is the first line\x0d\x0a...\x0d\x0aone dot\x0d\x0a....\x0d\x0atwo dots\x0d\x0a.....\x0d\x0athree... \x0d\x0a...\x0d\x0a..\x0d\x0a", "this is the first line\x0d\x0a..\x0d\x0aone dot\x0d\x0a...\x0d\x0atwo dots\x0d\x0a....\x0d\x0athree... \x0d\x0a..\x0d\x0a.\x0d\x0a"); } - void testCRLFToLFFilteredOutputStream() - { + void testCRLFToLFFilteredOutputStream() { + typedef vmime::utility::CRLFToLFFilteredOutputStream FILTER; testFilteredOutputStreamHelper("1", "foo\nbar", "foo\r\nbar"); @@ -193,12 +202,17 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) // stopSequenceFilteredInputStream template - void testStopSequenceFISHelper - (const std::string& number, const std::string& sequence, - const std::string& expected, const std::string& c1, - const std::string& c2 = "", const std::string& c3 = "", - const std::string& c4 = "", const std::string& c5 = "") - { + void testStopSequenceFISHelper( + const std::string& number, + const std::string& sequence, + const std::string& expected, + const std::string& c1, + const std::string& c2 = "", + const std::string& c3 = "", + const std::string& c4 = "", + const std::string& c5 = "" + ) { + chunkInputStream cis; cis.addChunk(c1); if (!c2.empty()) cis.addChunk(c2); @@ -211,8 +225,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) VASSERT_EQ(number, expected, readWhole(is)); } - void testStopSequenceFilteredInputStream1() - { + void testStopSequenceFilteredInputStream1() { + testStopSequenceFISHelper <1>("1", "x", "foo", "fooxbar"); testStopSequenceFISHelper <1>("2", "x", "foo", "foox", "bar"); testStopSequenceFISHelper <1>("3", "x", "foo", "foo", "x", "bar"); @@ -231,8 +245,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) testStopSequenceFISHelper <1>("13", "x", "", "", "x"); } - void testStopSequenceFilteredInputStreamN_2() - { + void testStopSequenceFilteredInputStreamN_2() { + testStopSequenceFISHelper <2>("1", "xy", "foo", "fooxybar"); testStopSequenceFISHelper <2>("2", "xy", "foo", "foox", "ybar"); testStopSequenceFISHelper <2>("3", "xy", "foo", "foox", "y", "bar"); @@ -255,8 +269,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) testStopSequenceFISHelper <2>("17", "xy", "", "x", "y"); } - void testStopSequenceFilteredInputStreamN_3() - { + void testStopSequenceFilteredInputStreamN_3() { + testStopSequenceFISHelper <3>("1", "xyz", "foo", "fooxyzbar"); testStopSequenceFISHelper <3>("2", "xyz", "foo", "foox", "yzbar"); testStopSequenceFISHelper <3>("3", "xyz", "foo", "foox", "y", "zbar"); @@ -289,8 +303,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) // LFToCRLFFilteredOutputStream - void testLFToCRLFFilteredOutputStream_Global() - { + void testLFToCRLFFilteredOutputStream_Global() { + typedef vmime::utility::LFToCRLFFilteredOutputStream FILTER; testFilteredOutputStreamHelper("1", "ABC\r\nDEF", "ABC\nDEF"); @@ -306,8 +320,8 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) testFilteredOutputStreamHelper("11", "\r\n\r\n\r\n\r\n", "\n\n\n\r\n"); } - void testLFToCRLFFilteredOutputStream_Edge() - { + void testLFToCRLFFilteredOutputStream_Edge() { + typedef vmime::utility::LFToCRLFFilteredOutputStream FILTER; testFilteredOutputStreamHelper("1", "\r\n\r\n", "\r", "\r"); @@ -325,4 +339,3 @@ VMIME_TEST_SUITE_BEGIN(filteredStreamTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/outputStreamByteArrayAdapterTest.cpp b/tests/utility/outputStreamByteArrayAdapterTest.cpp index b14d0a39..07a0f4b9 100644 --- a/tests/utility/outputStreamByteArrayAdapterTest.cpp +++ b/tests/utility/outputStreamByteArrayAdapterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest) VMIME_TEST_LIST_END - void testWrite() - { + void testWrite() { + vmime::byteArray bytes; vmime::utility::outputStreamByteArrayAdapter stream(bytes); @@ -50,8 +50,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest) VASSERT_EQ("Write 2", 0, memcmp("some datamore data", &bytes[0], 18)); } - void testWriteBinary() - { + void testWriteBinary() { + const char binaryData[] = "\xc5\x9a\xc3\xb8\xc9\xb1\xc9\x9b\x20\xc9\x93\xc9\xa8\xc9\xb2\xc9" "\x91\xc5\x95\xc9\xa3\x20\xc9\x96\xc9\x90\xca\x88\xc9\x92"; @@ -65,8 +65,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest) VASSERT_EQ("Write", 0, memcmp(binaryData, &bytes[0], sizeof(binaryData))); } - void testWriteCRLF() - { + void testWriteCRLF() { + vmime::byteArray bytes; vmime::utility::outputStreamByteArrayAdapter stream(bytes); @@ -80,4 +80,3 @@ VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/outputStreamSocketAdapterTest.cpp b/tests/utility/outputStreamSocketAdapterTest.cpp index 4920a75c..a869ed74 100644 --- a/tests/utility/outputStreamSocketAdapterTest.cpp +++ b/tests/utility/outputStreamSocketAdapterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest) VMIME_TEST_LIST_END - void testWrite() - { + void testWrite() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::utility::outputStreamSocketAdapter stream(*socket); @@ -49,8 +49,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest) VASSERT_EQ("Write", "some data", buffer); } - void testWriteBinary() - { + void testWriteBinary() { + const char binaryData[] = "\xc5\x9a\xc3\xb8\xc9\xb1\xc9\x9b\x20\xc9\x93\xc9\xa8\xc9\xb2\xc9" "\x91\xc5\x95\xc9\xa3\x20\xc9\x96\xc9\x90\xca\x88\xc9\x92"; @@ -67,8 +67,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest) VASSERT_EQ("Write", 0, memcmp(binaryData, buffer.data(), sizeof(binaryData))); } - void testWriteCRLF() - { + void testWriteCRLF() { + vmime::shared_ptr socket = vmime::make_shared (); vmime::utility::outputStreamSocketAdapter stream(*socket); @@ -85,4 +85,3 @@ VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/outputStreamStringAdapterTest.cpp b/tests/utility/outputStreamStringAdapterTest.cpp index 1cd3b3a0..3de8f8b8 100644 --- a/tests/utility/outputStreamStringAdapterTest.cpp +++ b/tests/utility/outputStreamStringAdapterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -35,8 +35,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest) VMIME_TEST_LIST_END - void testWrite() - { + void testWrite() { + vmime::string str("initial data"); vmime::utility::outputStreamStringAdapter stream(str); @@ -52,8 +52,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest) VASSERT_EQ("Write 2 data", "initial dataadditional datamore data", str); } - void testWriteBinary() - { + void testWriteBinary() { + const vmime::byte_t binaryData[] = "\xc5\x9a\xc3\xb8\xc9\xb1\xc9\x9b\x20\xc9\x93\xc9\xa8\xc9\xb2\xc9" "\x91\xc5\x95\xc9\xa3\x20\xc9\x96\xc9\x90\xca\x88\xc9\x92"; @@ -67,8 +67,8 @@ VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest) VASSERT_EQ("Write", 0, memcmp(binaryData, str.data(), sizeof(binaryData))); } - void testWriteCRLF() - { + void testWriteCRLF() { + vmime::string str; vmime::utility::outputStreamStringAdapter stream(str); @@ -82,4 +82,3 @@ VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/parserInputStreamAdapterTest.cpp b/tests/utility/parserInputStreamAdapterTest.cpp index 0fd4f4e8..4bc310c9 100644 --- a/tests/utility/parserInputStreamAdapterTest.cpp +++ b/tests/utility/parserInputStreamAdapterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -33,8 +33,8 @@ VMIME_TEST_SUITE_BEGIN(parserInputStreamAdapterTest) VMIME_TEST_LIST_END - void testEndlessLoopBufferSize() - { + void testEndlessLoopBufferSize() { + static const unsigned int BUFFER_SIZE = 4096; // same as in parserInputStreamAdapter::findNext() vmime::string str(BUFFER_SIZE, 'X'); diff --git a/tests/utility/pathTest.cpp b/tests/utility/pathTest.cpp index ef1b773d..e6227f3a 100644 --- a/tests/utility/pathTest.cpp +++ b/tests/utility/pathTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -64,14 +64,14 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) typedef vmime::utility::path::component comp; - void testConstruct1() - { + void testConstruct1() { + VASSERT_EQ("1", true, path().isEmpty()); VASSERT_EQ("2", 0, path().getSize()); } - void testConstruct2() - { + void testConstruct2() { + path p(comp("foo")); VASSERT_EQ("1", false, p.isEmpty()); @@ -79,8 +79,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", "foo", p.getComponentAt(0).getBuffer()); } - void testAppendComponent() - { + void testAppendComponent() { + path p; VASSERT_EQ("1", 0, p.getSize()); @@ -92,8 +92,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", c.getBuffer(), p.getComponentAt(0).getBuffer()); } - void testConstruct3() - { + void testConstruct3() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -105,8 +105,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", "bar", p2.getComponentAt(1).getBuffer()); } - void testConstruct4() - { + void testConstruct4() { + // Same as path::path(const component&) path p("foo"); @@ -115,8 +115,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", "foo", p.getComponentAt(0).getBuffer()); } - void testOperatorDiv1() - { + void testOperatorDiv1() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -132,8 +132,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer()); } - void testOperatorDiv2() - { + void testOperatorDiv2() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -148,8 +148,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", c.getBuffer(), p2.getComponentAt(2).getBuffer()); } - void testOperatorDivEqual1() - { + void testOperatorDivEqual1() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -166,8 +166,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer()); } - void testOperatorDivEqual2() - { + void testOperatorDivEqual2() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -183,8 +183,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", c.getBuffer(), p2.getComponentAt(2).getBuffer()); } - void testGetParent() - { + void testGetParent() { + path p1; path p1p = p1.getParent(); @@ -200,8 +200,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", p2.getComponentAt(0).getBuffer(), p2p.getComponentAt(0).getBuffer()); } - void testComparison() - { + void testComparison() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -224,8 +224,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("5", true, p3.getParent() == p1); } - void testGetLastComponent() - { + void testGetLastComponent() { + path p1; p1.appendComponent(comp("foo")); p1.appendComponent(comp("bar")); @@ -236,8 +236,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("3", "foo", p1.getParent().getParent().getLastComponent().getBuffer()); } - void testIsDirectParentOf() - { + void testIsDirectParentOf() { + path p1; p1.appendComponent(comp("foo")); @@ -256,8 +256,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", false, p2.isDirectParentOf(p1)); } - void testIsParentOf() - { + void testIsParentOf() { + path p1; p1.appendComponent(comp("foo")); @@ -276,8 +276,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("4", false, p2.isParentOf(p1)); } - void testIsParentOf_EquivalentCharset() - { + void testIsParentOf_EquivalentCharset() { + path p1; p1.appendComponent(comp("foo", "us-ascii")); @@ -289,8 +289,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("1", true, p1.isParentOf(p2)); } - void testRenameParent() - { + void testRenameParent() { + path p1; p1.appendComponent(comp("a")); p1.appendComponent(comp("b")); @@ -317,8 +317,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("6", "d", p.getComponentAt(4).getBuffer()); } - void testFromString() - { + void testFromString() { + path p = path::fromString("ab/cde/f", "/", vmime::charset("my-charset")); VASSERT_EQ("count", 3, p.getSize()); @@ -330,8 +330,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("charset3", "my-charset", p.getComponentAt(2).getCharset().getName()); } - void testFromString_IgnoreLeadingOrTrailingSep() - { + void testFromString_IgnoreLeadingOrTrailingSep() { + path p = path::fromString("//ab/cde/f////", "/", vmime::charset("my-charset")); VASSERT_EQ("count", 3, p.getSize()); @@ -343,8 +343,8 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) VASSERT_EQ("charset3", "my-charset", p.getComponentAt(2).getCharset().getName()); } - void testToString() - { + void testToString() { + path p; p.appendComponent(comp("ab")); p.appendComponent(comp("cde")); @@ -354,4 +354,3 @@ VMIME_TEST_SUITE_BEGIN(utilityPathTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/seekableInputStreamRegionAdapterTest.cpp b/tests/utility/seekableInputStreamRegionAdapterTest.cpp index e703051b..b099cd77 100644 --- a/tests/utility/seekableInputStreamRegionAdapterTest.cpp +++ b/tests/utility/seekableInputStreamRegionAdapterTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -43,9 +43,10 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VMIME_TEST_LIST_END - vmime::shared_ptr createStream - (vmime::shared_ptr * underlyingStream = NULL) - { + vmime::shared_ptr createStream( + vmime::shared_ptr * underlyingStream = NULL + ) { + vmime::string buffer("THIS IS A TEST BUFFER"); vmime::shared_ptr strStream = @@ -54,22 +55,23 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) vmime::shared_ptr rgnStream = vmime::make_shared (strStream, 10, 11); - if (underlyingStream) + if (underlyingStream) { *underlyingStream = strStream; + } return rgnStream; } - void testInitialPosition() - { + void testInitialPosition() { + vmime::shared_ptr stream = createStream(); VASSERT_EQ("Pos", 0, stream->getPosition()); VASSERT_FALSE("EOF", stream->eof()); } - void testSeekAndGetPosition() - { + void testSeekAndGetPosition() { + vmime::shared_ptr stream = createStream(); stream->seek(5); @@ -83,8 +85,8 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_TRUE("EOF 2", stream->eof()); } - void testRead() - { + void testRead() { + vmime::shared_ptr stream = createStream(); stream->seek(5); @@ -96,12 +98,11 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_EQ("Pos", 11, stream->getPosition()); VASSERT_EQ("Read", 6, read); VASSERT_TRUE("EOF", stream->eof()); - VASSERT_EQ("Buffer", "BUFFER", - vmime::utility::stringUtils::makeStringFromBytes(buffer, 6)); + VASSERT_EQ("Buffer", "BUFFER", vmime::utility::stringUtils::makeStringFromBytes(buffer, 6)); } - void testSkip() - { + void testSkip() { + vmime::shared_ptr stream = createStream(); stream->skip(5); @@ -116,8 +117,7 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_EQ("Pos 2", 8, stream->getPosition()); VASSERT_EQ("Read", 3, read); VASSERT_FALSE("EOF 2", stream->eof()); - VASSERT_EQ("Buffer", "BUF", - vmime::utility::stringUtils::makeStringFromBytes(buffer, 3)); + VASSERT_EQ("Buffer", "BUF", vmime::utility::stringUtils::makeStringFromBytes(buffer, 3)); stream->skip(50); @@ -125,8 +125,8 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_TRUE("EOF 3", stream->eof()); } - void testReset() - { + void testReset() { + vmime::shared_ptr stream = createStream(); stream->skip(100); @@ -136,8 +136,8 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_FALSE("EOF", stream->eof()); } - void testOwnPosition() - { + void testOwnPosition() { + // seekableInputStreamRegionAdapter should keep track of its own position // in the underlying stream, and not be affected by possible seek/read // operations on it... @@ -156,10 +156,17 @@ VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest) VASSERT_EQ("Read 2", 6, stream->read(buffer2, 6)); - VASSERT_EQ("Buffer 1", "THIS IS", - vmime::utility::stringUtils::makeStringFromBytes(buffer1, 7)); - VASSERT_EQ("Buffer 2", "BUFFER", - vmime::utility::stringUtils::makeStringFromBytes(buffer2, 6)); + VASSERT_EQ( + "Buffer 1", + "THIS IS", + vmime::utility::stringUtils::makeStringFromBytes(buffer1, 7) + ); + + VASSERT_EQ( + "Buffer 2", + "BUFFER", + vmime::utility::stringUtils::makeStringFromBytes(buffer2, 6) + ); // ...but the underlying stream position is affected by read operations // from the region adapter (FIXME?) diff --git a/tests/utility/stringProxyTest.cpp b/tests/utility/stringProxyTest.cpp index d6513681..89b96568 100644 --- a/tests/utility/stringProxyTest.cpp +++ b/tests/utility/stringProxyTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -41,8 +41,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VMIME_TEST_LIST_END - void testConstruct() - { + void testConstruct() { + vmime::utility::stringProxy s; VASSERT_EQ("1", static_cast (0), s.length()); @@ -50,8 +50,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("3", static_cast (0), s.end()); } - void testConstruct2() - { + void testConstruct2() { + vmime::string str("This is a test string."); vmime::utility::stringProxy s1(str); @@ -78,8 +78,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("13", 't', *(s3.it_begin() + 3)); } - void testDetach() - { + void testDetach() { + vmime::utility::stringProxy s; s = "foo"; @@ -90,8 +90,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("3", static_cast (0), s.end()); } - void testSet() - { + void testSet() { + vmime::string str("This is a test string."); vmime::utility::stringProxy s1; @@ -121,8 +121,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("13", 't', *(s3.it_begin() + 3)); } - void testExtract() - { + void testExtract() { + vmime::string str("This is a test string."); vmime::utility::stringProxy s1(str, 10, 14); @@ -144,8 +144,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("2", str, oss2.str()); } - void testOperatorLTLT1() - { + void testOperatorLTLT1() { + vmime::string str("This is a test string."); vmime::utility::stringProxy s1(str, 10, 14); @@ -163,8 +163,8 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) VASSERT_EQ("2", str, oss2.str()); } - void testOperatorLTLT2() - { + void testOperatorLTLT2() { + vmime::string str("This is a test string."); vmime::utility::stringProxy s1(str, 10, 14); @@ -187,4 +187,3 @@ VMIME_TEST_SUITE_BEGIN(stringProxyTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp index d86bbda0..393482f3 100644 --- a/tests/utility/stringUtilsTest.cpp +++ b/tests/utility/stringUtilsTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -52,8 +52,8 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) typedef vmime::utility::stringUtils stringUtils; - void testMakeStringFromBytes() - { + void testMakeStringFromBytes() { + vmime::byte_t bytes[] = { 0x12, 0x34, 0x56, 0x78 }; vmime::string str = vmime::utility::stringUtils::makeStringFromBytes(bytes, 3); @@ -63,8 +63,8 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("byte3", '\x56', str[2]); } - void testAppendBytesToString() - { + void testAppendBytesToString() { + vmime::byte_t bytes[] = { 0x42, 0x56, 0x12, 0x00, 'f', 'o', 'o' }; vmime::string str = "test"; @@ -84,8 +84,8 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("byte11", 'o', str[10]); } - void testIsStringEqualNoCase1() - { + void testIsStringEqualNoCase1() { + VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), "foo", 3)); VASSERT_EQ("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), "foo", 3)); @@ -93,15 +93,15 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3)); } - void testIsStringEqualNoCase2() - { + void testIsStringEqualNoCase2() { + VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo"))); VASSERT_EQ("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo"))); VASSERT_EQ("3", true, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo"))); } - void testIsStringEqualNoCase3() - { + void testIsStringEqualNoCase3() { + vmime::string str1("FooBar"); VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "foobar", 6)); @@ -110,15 +110,15 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6)); } - void testToLower() - { + void testToLower() { + VASSERT_EQ("1", "foo", stringUtils::toLower("FOO")); VASSERT_EQ("2", "foo", stringUtils::toLower("foO")); VASSERT_EQ("3", "foo", stringUtils::toLower("foo")); } - void testTrim() - { + void testTrim() { + VASSERT_EQ("1", "foo", stringUtils::trim(" foo")); VASSERT_EQ("2", "foo", stringUtils::trim("\t\tfoo")); VASSERT_EQ("3", "foo", stringUtils::trim(" \t \tfoo")); @@ -136,35 +136,47 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("13", "foo", stringUtils::trim("\r \tfoo \n\t")); } - void testCountASCIIChars() - { + void testCountASCIIChars() { + vmime::string str1("foo"); - VASSERT_EQ("1", static_cast (3), - stringUtils::countASCIIchars(str1.begin(), str1.end())); + VASSERT_EQ( + "1", + static_cast (3), + stringUtils::countASCIIchars(str1.begin(), str1.end()) + ); vmime::string str2("f=?oo"); - VASSERT_EQ("2", static_cast (3 + 1), - stringUtils::countASCIIchars(str2.begin(), str2.end())); + VASSERT_EQ( + "2", + static_cast (3 + 1), + stringUtils::countASCIIchars(str2.begin(), str2.end()) + ); vmime::string str3("foo\x7f"); - VASSERT_EQ("3", static_cast (4), - stringUtils::countASCIIchars(str3.begin(), str3.end())); + VASSERT_EQ( + "3", + static_cast (4), + stringUtils::countASCIIchars(str3.begin(), str3.end()) + ); vmime::string str4("foo\x80"); - VASSERT_EQ("4", static_cast (3), - stringUtils::countASCIIchars(str4.begin(), str4.end())); + VASSERT_EQ( + "4", + static_cast (3), + stringUtils::countASCIIchars(str4.begin(), str4.end()) + ); } - void testUnquote() - { + void testUnquote() { + VASSERT_EQ("1", "quoted", stringUtils::unquote("\"quoted\"")); // "quoted" VASSERT_EQ("2", "\"not quoted", stringUtils::unquote("\"not quoted")); // "not quoted VASSERT_EQ("3", "not quoted\"", stringUtils::unquote("not quoted\"")); // not quoted" VASSERT_EQ("4", "quoted with \"escape\"", stringUtils::unquote("\"quoted with \\\"escape\\\"\"")); // "quoted with \"escape\"" } - void testIsValidHostname() - { + void testIsValidHostname() { + VASSERT_TRUE ("1", stringUtils::isValidHostname("localhost")); VASSERT_TRUE ("2", stringUtils::isValidHostname("localhost.localdomain")); VASSERT_TRUE ("3", stringUtils::isValidHostname("example.com")); @@ -176,8 +188,8 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_FALSE("9", stringUtils::isValidHostname("-example.com")); } - void testIsValidFQDN() - { + void testIsValidFQDN() { + VASSERT_FALSE("1", stringUtils::isValidFQDN("localhost")); VASSERT_FALSE("2", stringUtils::isValidFQDN("localhost.localdomain")); VASSERT_FALSE("3", stringUtils::isValidFQDN("example.com")); @@ -189,4 +201,3 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) } VMIME_TEST_SUITE_END - diff --git a/tests/utility/urlTest.cpp b/tests/utility/urlTest.cpp index 85991511..36820a68 100644 --- a/tests/utility/urlTest.cpp +++ b/tests/utility/urlTest.cpp @@ -1,6 +1,6 @@ // // VMime library (http://www.vmime.org) -// Copyright (C) 2002-2013 Vincent Richard +// Copyright (C) 2002 Vincent Richard // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -44,14 +44,14 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VMIME_TEST_LIST_END - static bool parseHelper(vmime::utility::url& u, const vmime::string& str) - { - try - { + static bool parseHelper(vmime::utility::url& u, const vmime::string& str) { + + try { + u = vmime::utility::url(str); - } - catch (vmime::exceptions::malformed_url) - { + + } catch (vmime::exceptions::malformed_url) { + return false; } @@ -59,8 +59,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) } - void testParse1() - { + void testParse1() { + // Test some valid constructions vmime::utility::url u1("", ""); @@ -123,8 +123,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VASSERT_EQ("6.7", "/path/file", u4.getPath()); } - void testParse2() - { + void testParse2() { + // Now, test some ill-formed URLs // -- missing protocol @@ -144,8 +144,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VASSERT_EQ("4", false, parseHelper(u4, "protohost/path")); } - void testParse3() - { + void testParse3() { + // Test decoding vmime::utility::url u1("", ""); @@ -158,8 +158,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VASSERT_EQ("1.7", "/pa\xabth/", u1.getPath()); } - void testParse4() - { + void testParse4() { + // Test parameters vmime::utility::url u1("", ""); @@ -191,8 +191,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) } // '@' symbol in the username part - void testParse5() - { + void testParse5() { + vmime::utility::url u1("", ""); VASSERT_EQ("1", true, parseHelper(u1, "imap://account@myserver.com:password@myserver.com")); @@ -201,42 +201,54 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VASSERT_EQ("4", "myserver.com", u1.getHost()); } - void testGenerate() - { + void testGenerate() { + vmime::utility::url u1("proto", "host", 12345, "path", "user", "password"); - VASSERT_EQ("1", "proto://user:password@host:12345/path", - static_cast (u1)); + VASSERT_EQ( + "1", + "proto://user:password@host:12345/path", + static_cast (u1) + ); vmime::utility::url u2("proto", "host"); VASSERT_EQ("2", "proto://host", static_cast (u2)); vmime::utility::url u3("proto", "host"); u3.getParams()["p1"] = "v1"; - VASSERT_EQ("3.1", "proto://host/?p1=v1", - static_cast (u3)); + VASSERT_EQ( + "3.1", + "proto://host/?p1=v1", + static_cast (u3) + ); u3.getParams()["p2"] = "v2"; - VASSERT_EQ("3.2", "proto://host/?p1=v1&p2=v2", - static_cast (u3)); + VASSERT_EQ( + "3.2", + "proto://host/?p1=v1&p2=v2", + static_cast (u3) + ); // Test special characters u3.getParams().clear(); u3.getParams()["&"] = "="; - VASSERT_EQ("3.3", "proto://host/?%26=%3D", - static_cast (u3)); + VASSERT_EQ( + "3.3", + "proto://host/?%26=%3D", + static_cast (u3) + ); } - void testUtilsEncode() - { + void testUtilsEncode() { + VASSERT_EQ("1", "%01", vmime::utility::urlUtils::encode("\x01")); VASSERT_EQ("2", "%20", vmime::utility::urlUtils::encode(" ")); VASSERT_EQ("3", "%FF", vmime::utility::urlUtils::encode("\xff")); VASSERT_EQ("4", "a", vmime::utility::urlUtils::encode("a")); } - void testUtilsDecode() - { - for (int i = 0 ; i < 255 ; ++i) - { + void testUtilsDecode() { + + for (int i = 0 ; i < 255 ; ++i) { + std::ostringstream ossTest; ossTest << "%" << "0123456789ABCDEF"[i / 16] << "0123456789ABCDEF"[i % 16]; @@ -247,22 +259,25 @@ VMIME_TEST_SUITE_BEGIN(urlTest) vmime::string res; res += static_cast (i); - VASSERT_EQ(ossNum.str(), res, - vmime::utility::urlUtils::decode(ossTest.str())); + VASSERT_EQ( + ossNum.str(), + res, + vmime::utility::urlUtils::decode(ossTest.str()) + ); } } - void testUtilsDecodeSpecialCases() - { + void testUtilsDecodeSpecialCases() { + // Bug #1656547: segfault with '%' at the end of the string VASSERT_EQ("1.1", "sadfsda%", vmime::utility::urlUtils::decode("sadfsda%")); VASSERT_EQ("1.2", "sadfsda\x05", vmime::utility::urlUtils::decode("sadfsda%5")); VASSERT_EQ("1.3", "sadfsda\x42", vmime::utility::urlUtils::decode("sadfsda%42")); } - void testUtilsEncodeReservedChars() - { + void testUtilsEncodeReservedChars() { + VASSERT_EQ("1", "%24", vmime::utility::urlUtils::encode("$")); VASSERT_EQ("2", "%26", vmime::utility::urlUtils::encode("&")); VASSERT_EQ("3", "%2B", vmime::utility::urlUtils::encode("+")); @@ -275,8 +290,8 @@ VMIME_TEST_SUITE_BEGIN(urlTest) VASSERT_EQ("10", "%40", vmime::utility::urlUtils::encode("@")); } - void testUtilsEncodeUnsafeChars() - { + void testUtilsEncodeUnsafeChars() { + VASSERT_EQ("1", "%20", vmime::utility::urlUtils::encode(" ")); VASSERT_EQ("2", "%22", vmime::utility::urlUtils::encode("\"")); VASSERT_EQ("3", "%3C", vmime::utility::urlUtils::encode("<")); @@ -295,4 +310,3 @@ VMIME_TEST_SUITE_BEGIN(urlTest) } VMIME_TEST_SUITE_END - From 3bd864efc21ca6aa8f67521b4ef6f6410d66fba2 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 6 Sep 2018 00:05:13 +0200 Subject: [PATCH 23/27] Fixed possible memory leak. --- src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 93f1b763..73d52231 100644 --- a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp @@ -468,6 +468,11 @@ shared_ptr TLSSocket_GnuTLS::getPeerCertifica int res = gnutls_x509_crt_import(x509Certs[i], rawData + i, GNUTLS_X509_FMT_DER); if (res < 0) { + + for (unsigned int j = 0 ; j <= i ; ++j) { + gnutls_x509_crt_deinit(x509Certs[j]); + } + // XXX more fine-grained error reporting? delete [] x509Certs; return null; From 258f943ded1298973e04a82702315e86e015ce5f Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 6 Sep 2018 00:13:24 +0200 Subject: [PATCH 24/27] Moved implementation. --- src/vmime/net/store.cpp | 57 +++++++++++++++++++++++++++++++++++++++++ src/vmime/net/store.hpp | 10 ++------ 2 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 src/vmime/net/store.cpp diff --git a/src/vmime/net/store.cpp b/src/vmime/net/store.cpp new file mode 100644 index 00000000..3c9a66d6 --- /dev/null +++ b/src/vmime/net/store.cpp @@ -0,0 +1,57 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 Vincent Richard +// +// 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 "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/store.hpp" + + +namespace vmime { +namespace net { + + +store::store( + const shared_ptr & sess, + const serviceInfos& infos, + const shared_ptr & auth +) + : service(sess, infos, auth) { + +} + + +store::Type store::getType() const { + + return TYPE_STORE; +} + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/src/vmime/net/store.hpp b/src/vmime/net/store.hpp index 49b8ca3b..a96f2673 100644 --- a/src/vmime/net/store.hpp +++ b/src/vmime/net/store.hpp @@ -50,10 +50,7 @@ protected: const shared_ptr & sess, const serviceInfos& infos, const shared_ptr & auth - ) - : service(sess, infos, auth) { - - } + ); public: @@ -105,10 +102,7 @@ public: virtual int getCapabilities() const = 0; - Type getType() const { - - return TYPE_STORE; - } + Type getType() const; }; From 7e29cf01fa76e42a017f94294cead3e577d69d69 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 6 Sep 2018 00:16:48 +0200 Subject: [PATCH 25/27] Fixed bug in implementation of isStringEqualNoCase(). --- src/vmime/utility/stringUtils.cpp | 2 +- tests/utility/stringUtilsTest.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vmime/utility/stringUtils.cpp b/src/vmime/utility/stringUtils.cpp index 5f3c727a..823a3ea5 100644 --- a/src/vmime/utility/stringUtils.cpp +++ b/src/vmime/utility/stringUtils.cpp @@ -62,7 +62,7 @@ bool stringUtils::isStringEqualNoCase(const string& s1, const string& s2) { bool equal = true; const string::const_iterator end = s1.end(); - for (string::const_iterator i = s1.begin(), j = s2.begin(); i != end ; ++i, ++j) { + for (string::const_iterator i = s1.begin(), j = s2.begin() ; equal && i != end ; ++i, ++j) { equal = (fac.tolower(static_cast (*i)) == fac.tolower(static_cast (*j))); } diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp index 393482f3..49e16434 100644 --- a/tests/utility/stringUtilsTest.cpp +++ b/tests/utility/stringUtilsTest.cpp @@ -98,6 +98,9 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo"))); VASSERT_EQ("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo"))); VASSERT_EQ("3", true, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo"))); + + VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("bar"))); + VASSERT_EQ("5", false, stringUtils::isStringEqualNoCase(vmime::string("foOO"), vmime::string("barO"))); } void testIsStringEqualNoCase3() { From cfd4492915ef3c7f5e48c0f2aa02023efb8b506e Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 6 Sep 2018 00:22:34 +0200 Subject: [PATCH 26/27] More tests. --- tests/utility/stringUtilsTest.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp index 49e16434..6c2e18fb 100644 --- a/tests/utility/stringUtilsTest.cpp +++ b/tests/utility/stringUtilsTest.cpp @@ -91,6 +91,12 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("3", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "FOo", 3)); VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3)); + + VASSERT_EQ("5", false, stringUtils::isStringEqualNoCase(vmime::string("foO"), "bar", 3)); + VASSERT_EQ("6", false, stringUtils::isStringEqualNoCase(vmime::string("foOO"), "barO", 4)); + VASSERT_EQ("7", false, stringUtils::isStringEqualNoCase(vmime::string("foOO"), "ba", 2)); + + VASSERT_EQ("8", true, stringUtils::isStringEqualNoCase(vmime::string("FOoooo"), "foo", 3)); } void testIsStringEqualNoCase2() { @@ -111,6 +117,8 @@ VMIME_TEST_SUITE_BEGIN(stringUtilsTest) VASSERT_EQ("2", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "FooBar", 6)); VASSERT_EQ("3", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "fooBar", 3)); VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6)); + VASSERT_EQ("5", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "bar", 3)); + VASSERT_EQ("6", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 6, "barbar", 6)); } void testToLower() { From ea0d24809d24445f27b156b357b4b60be699b363 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 6 Sep 2018 20:09:54 +0200 Subject: [PATCH 27/27] Useless mutex does not make nl_langinfo() thread-safe. --- src/vmime/platforms/posix/posixHandler.cpp | 53 ++++------------------ 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/src/vmime/platforms/posix/posixHandler.cpp b/src/vmime/platforms/posix/posixHandler.cpp index 20c0f342..f8861315 100644 --- a/src/vmime/platforms/posix/posixHandler.cpp +++ b/src/vmime/platforms/posix/posixHandler.cpp @@ -55,9 +55,6 @@ #include #include -#if VMIME_HAVE_PTHREAD -# include -#endif // VMIME_HAVE_PTHREAD /* #ifdef _POSIX_PRIORITY_SCHEDULING @@ -66,45 +63,6 @@ */ -#if VMIME_HAVE_PTHREAD - -namespace { - - // This construction ensures mutex will be initialized in compile-time - // and will be available any time in the runtime. - pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; - - // Helper lock, to be exception safe all the time. - class PLockHelper { - - public: - - PLockHelper() { - - if (pthread_mutex_lock(&g_mutex) != 0) { - assert(!"unable to lock mutex - thread safety's void"); - } - } - - ~PLockHelper() { - - if (pthread_mutex_unlock(&g_mutex) != 0) { - assert(!"unable to unlock mutex - application's dead..."); - } - } - - private: - - // Object cannot be copied - PLockHelper(const PLockHelper&); - const PLockHelper& operator=(const PLockHelper&); - }; - -} // unnamed namespace - -#endif // VMIME_HAVE_PTHREAD - - namespace vmime { namespace platforms { namespace posix { @@ -173,9 +131,16 @@ const vmime::datetime posixHandler::getCurrentLocalTime() const { const vmime::charset posixHandler::getLocalCharset() const { - const PLockHelper lock; + // Note: nl_langinfo() might be affected by calls to setlocale() + // in a multithread environment. There is not MT-safe alternative + // to nl_langinfo(). + auto codeset = ::nl_langinfo(CODESET); - return vmime::charset(::nl_langinfo(CODESET)); + if (codeset) { + return vmime::charset(codeset); + } + + return vmime::charset(); }