ferencd@0: // ferencd@0: // VMime library (http://www.vmime.org) ferencd@0: // Copyright (C) 2002-2013 Vincent Richard ferencd@0: // ferencd@0: // This program is free software; you can redistribute it and/or ferencd@0: // modify it under the terms of the GNU General Public License as ferencd@0: // published by the Free Software Foundation; either version 3 of ferencd@0: // the License, or (at your option) any later version. ferencd@0: // ferencd@0: // This program is distributed in the hope that it will be useful, ferencd@0: // but WITHOUT ANY WARRANTY; without even the implied warranty of ferencd@0: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ferencd@0: // General Public License for more details. ferencd@0: // ferencd@0: // You should have received a copy of the GNU General Public License along ferencd@0: // with this program; if not, write to the Free Software Foundation, Inc., ferencd@0: // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ferencd@0: // ferencd@0: // Linking this library statically or dynamically with other modules is making ferencd@0: // a combined work based on this library. Thus, the terms and conditions of ferencd@0: // the GNU General Public License cover the whole combination. ferencd@0: // ferencd@0: ferencd@0: #include "testUtils.hpp" ferencd@0: ferencd@0: #include "vmime/utility/stringUtils.hpp" ferencd@0: ferencd@0: #include ferencd@0: ferencd@0: ferencd@0: ferencd@0: // testSocket ferencd@0: ferencd@0: void testSocket::connect(const vmime::string& address, const vmime::port_t port) ferencd@0: { ferencd@0: m_address = address; ferencd@0: m_port = port; ferencd@0: m_connected = true; ferencd@0: ferencd@0: onConnected(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::disconnect() ferencd@0: { ferencd@0: m_address.clear(); ferencd@0: m_port = 0; ferencd@0: m_connected = false; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testSocket::isConnected() const ferencd@0: { ferencd@0: return m_connected; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::size_t testSocket::getBlockSize() const ferencd@0: { ferencd@0: return 16384; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: unsigned int testSocket::getStatus() const ferencd@0: { ferencd@0: return 0; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: const vmime::string testSocket::getPeerName() const ferencd@0: { ferencd@0: return "test.vmime.org"; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: const vmime::string testSocket::getPeerAddress() const ferencd@0: { ferencd@0: return "127.0.0.1"; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::shared_ptr testSocket::getTimeoutHandler() ferencd@0: { ferencd@0: return vmime::null; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::setTracer(vmime::shared_ptr tracer) ferencd@0: { ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::shared_ptr testSocket::getTracer() ferencd@0: { ferencd@0: return vmime::null; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testSocket::waitForRead(const int msecs) ferencd@0: { ferencd@0: return true; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testSocket::waitForWrite(const int msecs) ferencd@0: { ferencd@0: return true; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::receive(vmime::string& buffer) ferencd@0: { ferencd@0: buffer = m_inBuffer; ferencd@0: m_inBuffer.clear(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::send(const vmime::string& buffer) ferencd@0: { ferencd@0: m_outBuffer += buffer; ferencd@0: ferencd@0: onDataReceived(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::send(const char* str) ferencd@0: { ferencd@0: sendRaw(reinterpret_cast (str), strlen(str)); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::size_t testSocket::receiveRaw(vmime::byte_t* buffer, const size_t count) ferencd@0: { ferencd@0: const size_t n = std::min(count, static_cast (m_inBuffer.size())); ferencd@0: ferencd@0: std::copy(m_inBuffer.begin(), m_inBuffer.begin() + n, buffer); ferencd@0: m_inBuffer.erase(m_inBuffer.begin(), m_inBuffer.begin() + n); ferencd@0: ferencd@0: return n; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::sendRaw(const vmime::byte_t* buffer, const size_t count) ferencd@0: { ferencd@0: send(vmime::utility::stringUtils::makeStringFromBytes(buffer, count)); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::size_t testSocket::sendRawNonBlocking(const vmime::byte_t* buffer, const size_t count) ferencd@0: { ferencd@0: sendRaw(buffer, count); ferencd@0: return count; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::localSend(const vmime::string& buffer) ferencd@0: { ferencd@0: m_inBuffer += buffer; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::localReceive(vmime::string& buffer) ferencd@0: { ferencd@0: buffer = m_outBuffer; ferencd@0: m_outBuffer.clear(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testSocket::localReceiveLine(vmime::string& line) ferencd@0: { ferencd@0: vmime::size_t eol; ferencd@0: ferencd@0: if ((eol = m_outBuffer.find('\n')) != vmime::string::npos) ferencd@0: { ferencd@0: line = vmime::string(m_outBuffer.begin(), m_outBuffer.begin() + eol); ferencd@0: ferencd@0: if (!line.empty() && line[line.length() - 1] == '\r') ferencd@0: line.erase(line.end() - 1, line.end()); ferencd@0: ferencd@0: m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + eol + 1); ferencd@0: ferencd@0: return true; ferencd@0: } ferencd@0: ferencd@0: return false; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: vmime::size_t testSocket::localReceiveRaw(vmime::byte_t* buffer, const size_t count) ferencd@0: { ferencd@0: const size_t received = std::min(count, static_cast (m_outBuffer.size())); ferencd@0: ferencd@0: if (received != 0) ferencd@0: { ferencd@0: if (buffer != NULL) ferencd@0: std::copy(m_outBuffer.begin(), m_outBuffer.begin() + received, buffer); ferencd@0: ferencd@0: m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + received); ferencd@0: } ferencd@0: ferencd@0: return received; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::onDataReceived() ferencd@0: { ferencd@0: // Override ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testSocket::onConnected() ferencd@0: { ferencd@0: // Override ferencd@0: } ferencd@0: ferencd@0: ferencd@0: // lineBasedTestSocket ferencd@0: ferencd@0: void lineBasedTestSocket::onDataReceived() ferencd@0: { ferencd@0: vmime::string chunk; ferencd@0: localReceive(chunk); ferencd@0: ferencd@0: m_buffer += chunk; ferencd@0: ferencd@0: vmime::size_t eol; ferencd@0: ferencd@0: while ((eol = m_buffer.find('\n')) != vmime::string::npos) ferencd@0: { ferencd@0: vmime::string line(std::string(m_buffer.begin(), m_buffer.begin() + eol)); ferencd@0: ferencd@0: if (!line.empty() && line[line.length() - 1] == '\r') ferencd@0: line.erase(line.end() - 1, line.end()); ferencd@0: ferencd@0: m_lines.push_back(line); ferencd@0: m_buffer.erase(m_buffer.begin(), m_buffer.begin() + eol + 1); ferencd@0: } ferencd@0: ferencd@0: while (!m_lines.empty()) ferencd@0: processCommand(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: const vmime::string lineBasedTestSocket::getNextLine() ferencd@0: { ferencd@0: const vmime::string line = m_lines.front(); ferencd@0: m_lines.erase(m_lines.begin(), m_lines.begin() + 1); ferencd@0: return line; ferencd@0: } ferencd@0: ferencd@0: bool lineBasedTestSocket::haveMoreLines() const ferencd@0: { ferencd@0: return !m_lines.empty(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: // testTimeoutHandler ferencd@0: ferencd@0: testTimeoutHandler::testTimeoutHandler(const unsigned long delay) ferencd@0: : m_delay(delay), m_start(0) ferencd@0: { ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testTimeoutHandler::isTimeOut() ferencd@0: { ferencd@0: return (vmime::platform::getHandler()->getUnixTime() - m_start) >= m_delay; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: void testTimeoutHandler::resetTimeOut() ferencd@0: { ferencd@0: m_start = vmime::platform::getHandler()->getUnixTime(); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: bool testTimeoutHandler::handleTimeOut() ferencd@0: { ferencd@0: return false; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: // testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory ferencd@0: ferencd@0: vmime::shared_ptr testTimeoutHandlerFactory::create() ferencd@0: { ferencd@0: return vmime::make_shared (); ferencd@0: } ferencd@0: ferencd@0: ferencd@0: ferencd@0: // Exception helper ferencd@0: std::ostream& operator<<(std::ostream& os, const vmime::exception& e) ferencd@0: { ferencd@0: os << "* vmime::exceptions::" << e.name() << std::endl; ferencd@0: os << " what = " << e.what() << std::endl; ferencd@0: ferencd@0: // More information for special exceptions ferencd@0: if (dynamic_cast (&e)) ferencd@0: { ferencd@0: const vmime::exceptions::command_error& cee = ferencd@0: dynamic_cast (e); ferencd@0: ferencd@0: os << " command = " << cee.command() << std::endl; ferencd@0: os << " response = " << cee.response() << std::endl; ferencd@0: } ferencd@0: ferencd@0: if (dynamic_cast (&e)) ferencd@0: { ferencd@0: const vmime::exceptions::invalid_response& ir = ferencd@0: dynamic_cast (e); ferencd@0: ferencd@0: os << " response = " << ir.response() << std::endl; ferencd@0: } ferencd@0: ferencd@0: if (dynamic_cast (&e)) ferencd@0: { ferencd@0: const vmime::exceptions::connection_greeting_error& cgee = ferencd@0: dynamic_cast (e); ferencd@0: ferencd@0: os << " response = " << cgee.response() << std::endl; ferencd@0: } ferencd@0: ferencd@0: if (dynamic_cast (&e)) ferencd@0: { ferencd@0: const vmime::exceptions::authentication_error& aee = ferencd@0: dynamic_cast (e); ferencd@0: ferencd@0: os << " response = " << aee.response() << std::endl; ferencd@0: } ferencd@0: ferencd@0: if (dynamic_cast (&e)) ferencd@0: { ferencd@0: const vmime::exceptions::filesystem_exception& fse = ferencd@0: dynamic_cast (e); ferencd@0: ferencd@0: os << " path = " << vmime::platform::getHandler()-> ferencd@0: getFileSystemFactory()->pathToString(fse.path()) << std::endl; ferencd@0: } ferencd@0: ferencd@0: if (e.other() != NULL) ferencd@0: os << *e.other(); ferencd@0: ferencd@0: return os; ferencd@0: } ferencd@0: ferencd@0: ferencd@0: const vmime::string toHex(const vmime::string str) ferencd@0: { ferencd@0: static const char hexChars[] = "0123456789abcdef"; ferencd@0: ferencd@0: vmime::string res = "\n"; ferencd@0: ferencd@0: for (size_t i = 0 ; i < str.length() ; i += 16) ferencd@0: { ferencd@0: size_t r = std::min ferencd@0: (static_cast (16), str.length() - i); ferencd@0: ferencd@0: vmime::string hex; ferencd@0: vmime::string chr; ferencd@0: ferencd@0: for (size_t j = 0 ; j < r ; ++j) ferencd@0: { ferencd@0: const unsigned char c = str[i + j]; ferencd@0: ferencd@0: hex += hexChars[c / 16]; ferencd@0: hex += hexChars[c % 16]; ferencd@0: hex += " "; ferencd@0: ferencd@0: if (c >= 32 && c <= 127) ferencd@0: chr += c; ferencd@0: else ferencd@0: chr += '.'; ferencd@0: } ferencd@0: ferencd@0: for (size_t j = r ; j < 16 ; ++j) ferencd@0: hex += " "; ferencd@0: ferencd@0: res += hex + " " + chr + "\n"; ferencd@0: } ferencd@0: ferencd@0: return res; ferencd@0: }