Service properties enhancement.

This commit is contained in:
Vincent Richard 2005-05-15 18:05:38 +00:00
parent 258cb13281
commit 8134a52f56
20 changed files with 861 additions and 185 deletions

View File

@ -2,6 +2,12 @@
VERSION 0.7.1cvs
================
2005-05-15 Vincent Richard <vincent@vincent-richard.net>
* messaging/serviceInfos.{hpp|cpp}: changed getAvailableProperties() to
return 'serviceInfos::property' objects instead of strings. This permits
setting service properties in a more generic manner.
2005-05-03 Vincent Richard <vincent@vincent-richard.net>
* messaging/imap/IMAPFolder.cpp: fixed missing space in "STATUS" command +

View File

@ -176,7 +176,8 @@ libvmime_examples_sources = [
'examples/example3.cpp',
'examples/example4.cpp',
'examples/example5.cpp',
'examples/example6.cpp'
'examples/example6.cpp',
'examples/example7.cpp'
]
libvmime_messaging_sources = [
@ -190,7 +191,7 @@ libvmime_messaging_sources = [
'messaging/message.cpp', 'messaging/message.hpp',
'messaging/service.cpp', 'messaging/service.hpp',
'messaging/serviceFactory.cpp', 'messaging/serviceFactory.hpp',
'messaging/serviceInfos.hpp',
'messaging/serviceInfos.cpp', 'messaging/serviceInfos.hpp',
'messaging/session.cpp', 'messaging/session.hpp',
'messaging/simpleAuthenticator.cpp', 'messaging/simpleAuthenticator.hpp',
'messaging/socket.hpp',

View File

@ -72,56 +72,6 @@ int main()
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
//
// Test the new enumeration system for encoders
//
#if 1
vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
std::cout << "Available encoders:" << std::endl;
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
{
const vmime::encoderFactory::registeredEncoder& enc = *ef->getEncoderAt(i);
std::cout << " * " << enc.getName() << std::endl;
vmime::encoder* e = enc.create();
std::vector <vmime::string> props = e->getAvailableProperties();
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
std::cout << " - " << *it << std::endl;
delete (e);
}
#endif
// ======================================================================================
//
// Test the new enumeration system for messaging services
//
#if 1
vmime::messaging::serviceFactory* sf = vmime::messaging::serviceFactory::getInstance();
std::cout << "Available messaging services:" << std::endl;
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
{
const vmime::messaging::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
std::cout << " * " << serv.getName() << " (" << serv.getInfos().getDefaultPort() << ")" << std::endl;
std::vector <vmime::string> props = serv.getInfos().getAvailableProperties();
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
std::cout << " - " << serv.getInfos().getPropertyPrefix() + *it << std::endl;
}
#endif
vmime::messaging::session sess;
sess.getProperties()["store.protocol"] = "imap";
sess.getProperties()["transport.protocol"] = "smtp";

110
examples/example7.cpp Normal file
View File

@ -0,0 +1,110 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
//
// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
// EXAMPLE DESCRIPTION:
// ====================
// This sample program demonstrates how to enumerate encoders and
// messaging services in VMime.
//
// For more information, please visit:
// http://www.vmime.org/
//
#include <iostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
// Enumerate encoders
vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
std::cout << "Available encoders:" << std::endl;
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
{
const vmime::encoderFactory::registeredEncoder& enc = *ef->getEncoderAt(i);
std::cout << " * " << enc.getName() << std::endl;
vmime::encoder* e = enc.create();
std::vector <vmime::string> props = e->getAvailableProperties();
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
std::cout << " - " << *it << std::endl;
delete (e);
}
std::cout << std::endl;
// Enumerate messaging services and their properties
vmime::messaging::serviceFactory* sf = vmime::messaging::serviceFactory::getInstance();
std::cout << "Available messaging services:" << std::endl;
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
{
const vmime::messaging::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
std::cout << " * " << serv.getName() << std::endl;
std::vector <vmime::messaging::serviceInfos::property> props =
serv.getInfos().getAvailableProperties();
for (std::vector <vmime::messaging::serviceInfos::property>::const_iterator it = props.begin() ;
it != props.end() ; ++it)
{
const vmime::messaging::serviceInfos::property& p = *it;
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
vmime::string type;
switch (p.getType())
{
case vmime::messaging::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
case vmime::messaging::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
case vmime::messaging::serviceInfos::property::TYPE_BOOL: type = "TYPE_BOOL"; break;
default: type = "(unknown)"; break;
}
vmime::string flags;
if (p.getFlags() & vmime::messaging::serviceInfos::property::FLAG_REQUIRED)
flags += " FLAG_REQUIRED";
if (p.getFlags() & vmime::messaging::serviceInfos::property::FLAG_HIDDEN)
flags += " FLAG_HIDDEN";
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
std::cout << " (type=" << type << ", flags=" << flags;
std::cout << ", defaultValue=" << p.getDefaultValue() << ")" << std::endl;
}
}
std::cout << std::endl;
}

View File

@ -28,6 +28,15 @@
#include <sstream>
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
(m_store->getInfos().getPropertyValue <type>(getSession(), \
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
#define HAS_PROPERTY(prop) \
(m_store->getInfos().hasProperty(getSession(), \
dynamic_cast <const IMAPStore::_infos&>(m_store->getInfos()).getProperties().prop))
namespace vmime {
namespace messaging {
namespace imap {
@ -60,28 +69,26 @@ void IMAPConnection::connect()
m_state = STATE_NONE;
m_hierarchySeparator = '\0';
const string address = m_store->getSession()->getProperties()[m_store->getInfos().getPropertyPrefix() + "server.address"];
const port_t port = m_store->getSession()->getProperties().getProperty(m_store->getInfos().getPropertyPrefix() + "server.port", m_store->getInfos().getDefaultPort());
const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS);
const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT);
// Create the time-out handler
if (m_store->getSession()->getProperties().hasProperty
(m_store->getInfos().getPropertyPrefix() + "timeout.factory"))
if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY))
{
timeoutHandlerFactory* tof = platformDependant::getHandler()->
getTimeoutHandlerFactory(m_store->getSession()->getProperties()
[m_store->getInfos().getPropertyPrefix() + "timeout.factory"]);
getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY));
m_timeoutHandler = tof->create();
}
// Create and connect the socket
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
(m_store->getSession()->getProperties().getProperty
(m_store->getInfos().getPropertyPrefix() + "server.socket-factory", string("default")));
socketFactory* sf = platformDependant::getHandler()->
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
m_socket = sf->create();
m_socket->connect(address, port);
delete (m_tag);
m_tag = new IMAPTag();
@ -260,6 +267,53 @@ IMAPParser::response* IMAPConnection::readResponse(IMAPParser::literalHandler* l
}
const IMAPConnection::ProtocolStates IMAPConnection::state() const
{
return (m_state);
}
void IMAPConnection::setState(const ProtocolStates state)
{
m_state = state;
}
const char IMAPConnection::hierarchySeparator() const
{
return (m_hierarchySeparator);
}
const IMAPTag* IMAPConnection::getTag() const
{
return (m_tag);
}
const IMAPParser* IMAPConnection::getParser() const
{
return (m_parser);
}
const IMAPStore* IMAPConnection::getStore() const
{
return (m_store);
}
IMAPStore* IMAPConnection::getStore()
{
return (m_store);
}
session* IMAPConnection::getSession()
{
return (m_store->getSession());
}
} // imap
} // messaging
} // vmime

View File

@ -238,7 +238,6 @@ const int IMAPStore::getCapabilities() const
// Service infos
IMAPStore::_infos IMAPStore::sm_infos;
@ -256,39 +255,57 @@ const serviceInfos& IMAPStore::getInfos() const
}
const port_t IMAPStore::_infos::getDefaultPort() const
{
return (143);
}
const string IMAPStore::_infos::getPropertyPrefix() const
{
return "store.imap.";
}
const std::vector <string> IMAPStore::_infos::getAvailableProperties() const
const IMAPStore::_infos::props& IMAPStore::_infos::getProperties() const
{
std::vector <string> list;
static props p =
{
// IMAP-specific options
//list.push_back("auth.mechanism");
// (none)
// Common properties
list.push_back("auth.username");
list.push_back("auth.password");
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
list.push_back("server.address");
list.push_back("server.port");
list.push_back("server.socket-factory");
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
property(serviceInfos::property::SERVER_PORT, "143"),
property(serviceInfos::property::SERVER_SOCKETFACTORY),
list.push_back("timeout.factory");
property(serviceInfos::property::TIMEOUT_FACTORY)
};
return p;
}
const std::vector <serviceInfos::property> IMAPStore::_infos::getAvailableProperties() const
{
std::vector <property> list;
const props& p = getProperties();
// IMAP-specific options
// (none)
// Common properties
list.push_back(p.PROPERTY_AUTH_USERNAME);
list.push_back(p.PROPERTY_AUTH_PASSWORD);
list.push_back(p.PROPERTY_SERVER_ADDRESS);
list.push_back(p.PROPERTY_SERVER_PORT);
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
return (list);
}
} // imap
} // messaging
} // vmime

View File

@ -27,6 +27,13 @@
#include "vmime/platformDependant.hpp"
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
#define HAS_PROPERTY(prop) \
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
namespace vmime {
namespace messaging {
namespace maildir {
@ -108,8 +115,7 @@ void maildirStore::connect()
// Get root directory
utility::fileSystemFactory* fsf = platformDependant::getHandler()->getFileSystemFactory();
m_fsPath = fsf->stringToPath
(getSession()->getProperties()[getInfos().getPropertyPrefix() + "server.rootpath"]);
m_fsPath = fsf->stringToPath(GET_PROPERTY(string, PROPERTY_SERVER_ROOTPATH));
utility::auto_ptr <utility::file> rootDir = fsf->create(m_fsPath);
@ -207,23 +213,30 @@ const serviceInfos& maildirStore::getInfos() const
}
const port_t maildirStore::_infos::getDefaultPort() const
{
return (0);
}
const string maildirStore::_infos::getPropertyPrefix() const
{
return "store.maildir.";
}
const std::vector <string> maildirStore::_infos::getAvailableProperties() const
const maildirStore::_infos::props& maildirStore::_infos::getProperties() const
{
std::vector <string> list;
static props p =
{
property(serviceInfos::property::SERVER_ROOTPATH, serviceInfos::property::FLAG_REQUIRED)
};
list.push_back("server.rootpath");
return p;
}
const std::vector <serviceInfos::property> maildirStore::_infos::getAvailableProperties() const
{
std::vector <property> list;
const props& p = getProperties();
// Maildir-specific properties
list.push_back(p.PROPERTY_SERVER_ROOTPATH);
return (list);
}

View File

@ -28,6 +28,13 @@
#include <algorithm>
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
#define HAS_PROPERTY(prop) \
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
namespace vmime {
namespace messaging {
namespace pop3 {
@ -93,23 +100,21 @@ void POP3Store::connect()
if (isConnected())
throw exceptions::already_connected();
const string address = getSession()->getProperties()[sm_infos.getPropertyPrefix() + "server.address"];
const port_t port = getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.port", sm_infos.getDefaultPort());
const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS);
const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT);
// Create the time-out handler
if (getSession()->getProperties().hasProperty
(sm_infos.getPropertyPrefix() + "timeout.factory"))
if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY))
{
timeoutHandlerFactory* tof = platformDependant::getHandler()->
getTimeoutHandlerFactory(getSession()->getProperties()
[sm_infos.getPropertyPrefix() + "timeout.factory"]);
getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY));
m_timeoutHandler = tof->create();
}
// Create and connect the socket
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
(getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.socket-factory", string("default")));
socketFactory* sf = platformDependant::getHandler()->
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
m_socket = sf->create();
m_socket->connect(address, port);
@ -134,7 +139,7 @@ void POP3Store::connect()
// --- S: +OK vincent is a valid mailbox
messageId mid(response);
if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "options.apop", false))
if (GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP))
{
if (mid.getLeft().length() && mid.getRight().length())
{
@ -149,8 +154,7 @@ void POP3Store::connect()
}
else
{
if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() +
"options.apop.fallback", false) == false)
if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK))
{
internalDisconnect();
throw exceptions::authentication_error(response);
@ -160,8 +164,7 @@ void POP3Store::connect()
else
{
// APOP not supported
if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() +
"options.apop.fallback", false) == false)
if (!GET_PROPERTY(bool, PROPERTY_OPTIONS_APOP_FALLBACK))
{
// Can't fallback on basic authentification
internalDisconnect();
@ -591,35 +594,53 @@ const serviceInfos& POP3Store::getInfos() const
}
const port_t POP3Store::_infos::getDefaultPort() const
{
return (110);
}
const string POP3Store::_infos::getPropertyPrefix() const
{
return "store.pop3.";
}
const std::vector <string> POP3Store::_infos::getAvailableProperties() const
const POP3Store::_infos::props& POP3Store::_infos::getProperties() const
{
std::vector <string> list;
static props p =
{
// POP3-specific options
list.push_back("options.apop");
list.push_back("options.apop.fallback");
property("options.apop", serviceInfos::property::TYPE_BOOL, "false"),
property("options.apop.fallback", serviceInfos::property::TYPE_BOOL, "false"),
// Common properties
list.push_back("auth.username");
list.push_back("auth.password");
property(serviceInfos::property::AUTH_USERNAME, serviceInfos::property::FLAG_REQUIRED),
property(serviceInfos::property::AUTH_PASSWORD, serviceInfos::property::FLAG_REQUIRED),
list.push_back("server.address");
list.push_back("server.port");
list.push_back("server.socket-factory");
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
property(serviceInfos::property::SERVER_PORT, "110"),
property(serviceInfos::property::SERVER_SOCKETFACTORY),
list.push_back("timeout.factory");
property(serviceInfos::property::TIMEOUT_FACTORY)
};
return p;
}
const std::vector <serviceInfos::property> POP3Store::_infos::getAvailableProperties() const
{
std::vector <property> list;
const props& p = getProperties();
// POP3-specific options
list.push_back(p.PROPERTY_OPTIONS_APOP);
list.push_back(p.PROPERTY_OPTIONS_APOP_FALLBACK);
// Common properties
list.push_back(p.PROPERTY_AUTH_USERNAME);
list.push_back(p.PROPERTY_AUTH_PASSWORD);
list.push_back(p.PROPERTY_SERVER_ADDRESS);
list.push_back(p.PROPERTY_SERVER_PORT);
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
return (list);
}

View File

@ -28,6 +28,15 @@
#include "vmime/utility/childProcess.hpp"
#include "vmime/utility/smartPtr.hpp"
#include "vmime/config.hpp"
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
#define HAS_PROPERTY(prop) \
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
#if VMIME_BUILTIN_PLATFORM_POSIX
@ -62,8 +71,7 @@ void sendmailTransport::connect()
throw exceptions::already_connected();
// Use the specified path for 'sendmail' or a default one if no path is specified
m_sendmailPath = getSession()->getProperties().getProperty
(sm_infos.getPropertyPrefix() + "binpath", string(VMIME_SENDMAIL_PATH));
m_sendmailPath = GET_PROPERTY(string, PROPERTY_BINPATH);
m_connected = true;
}
@ -177,24 +185,30 @@ const serviceInfos& sendmailTransport::getInfos() const
}
const port_t sendmailTransport::_infos::getDefaultPort() const
{
return (0);
}
const string sendmailTransport::_infos::getPropertyPrefix() const
{
return "transport.sendmail.";
}
const std::vector <string> sendmailTransport::_infos::getAvailableProperties() const
const sendmailTransport::_infos::props& sendmailTransport::_infos::getProperties() const
{
std::vector <string> list;
static props p =
{
// Path to sendmail (override default)
list.push_back("binpath");
property("binpath", serviceInfos::property::TYPE_STRING, string(VMIME_SENDMAIL_PATH))
};
return p;
}
const std::vector <serviceInfos::property> sendmailTransport::_infos::getAvailableProperties() const
{
std::vector <property> list;
const props& p = getProperties();
list.push_back(p.PROPERTY_BINPATH);
return (list);
}

View File

@ -0,0 +1,150 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
//
// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include "vmime/messaging/serviceInfos.hpp"
namespace vmime {
namespace messaging {
// Common properties
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_ROOTPATH
("server.rootpath", serviceInfos::property::TYPE_STRING);
const serviceInfos::property serviceInfos::property::SERVER_SOCKETFACTORY
("server.socket-factory", serviceInfos::property::TYPE_STRING, "default");
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::TIMEOUT_FACTORY
("timeout.factory", serviceInfos::property::TYPE_STRING);
// serviceInfos
serviceInfos::serviceInfos()
{
}
serviceInfos::serviceInfos(const serviceInfos&)
{
}
serviceInfos& serviceInfos::operator=(const serviceInfos&)
{
return (*this);
}
serviceInfos::~serviceInfos()
{
}
const bool serviceInfos::hasProperty(session* s, const property& p) const
{
return s->getProperties().hasProperty(getPropertyPrefix() + p.getName());
}
// 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 property& p, const int addFlags, const int removeFlags)
{
m_name = p.m_name;
m_type = p.m_type;
m_defaultValue = p.m_defaultValue;
m_flags = (p.m_flags | addFlags) & ~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;
m_flags = (p.m_flags | addFlags) & ~removeFlags;
}
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);
}
const string& serviceInfos::property::getName() const
{
return (m_name);
}
const string& serviceInfos::property::getDefaultValue() const
{
return (m_defaultValue);
}
const serviceInfos::property::Types serviceInfos::property::getType() const
{
return (m_type);
}
const int serviceInfos::property::getFlags() const
{
return (m_flags);
}
} // messaging
} // vmime

View File

@ -29,6 +29,13 @@
#include "vmime/utility/filteredStream.hpp"
// Helpers for service properties
#define GET_PROPERTY(type, prop) \
(sm_infos.getPropertyValue <type>(getSession(), sm_infos.getProperties().prop))
#define HAS_PROPERTY(prop) \
(sm_infos.hasProperty(getSession(), sm_infos.getProperties().prop))
namespace vmime {
namespace messaging {
namespace smtp {
@ -61,23 +68,21 @@ void SMTPTransport::connect()
if (isConnected())
throw exceptions::already_connected();
const string address = getSession()->getProperties()[sm_infos.getPropertyPrefix() + "server.address"];
const port_t port = getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.port", sm_infos.getDefaultPort());
const string address = GET_PROPERTY(string, PROPERTY_SERVER_ADDRESS);
const port_t port = GET_PROPERTY(port_t, PROPERTY_SERVER_PORT);
// Create the time-out handler
if (getSession()->getProperties().hasProperty
(sm_infos.getPropertyPrefix() + "timeout.factory"))
if (HAS_PROPERTY(PROPERTY_TIMEOUT_FACTORY))
{
timeoutHandlerFactory* tof = platformDependant::getHandler()->
getTimeoutHandlerFactory(getSession()->getProperties()
[sm_infos.getPropertyPrefix() + "timeout.factory"]);
getTimeoutHandlerFactory(GET_PROPERTY(string, PROPERTY_TIMEOUT_FACTORY));
m_timeoutHandler = tof->create();
}
// Create and connect the socket
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
(getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.socket-factory", string("default")));
socketFactory* sf = platformDependant::getHandler()->
getSocketFactory(GET_PROPERTY(string, PROPERTY_SERVER_SOCKETFACTORY));
m_socket = sf->create();
m_socket->connect(address, port);
@ -129,8 +134,7 @@ void SMTPTransport::connect()
}
// Authentication
if (getSession()->getProperties().getProperty
(sm_infos.getPropertyPrefix() + "options.need-authentication", false) == true)
if (GET_PROPERTY(bool, PROPERTY_OPTIONS_NEEDAUTH))
{
if (!m_extendedSMTP)
{
@ -447,34 +451,51 @@ const serviceInfos& SMTPTransport::getInfos() const
}
const port_t SMTPTransport::_infos::getDefaultPort() const
{
return (25);
}
const string SMTPTransport::_infos::getPropertyPrefix() const
{
return "transport.smtp.";
}
const std::vector <string> SMTPTransport::_infos::getAvailableProperties() const
const SMTPTransport::_infos::props& SMTPTransport::_infos::getProperties() const
{
std::vector <string> list;
static props p =
{
// SMTP-specific options
list.push_back("options.need-authentication");
property("options.need-authentication", serviceInfos::property::TYPE_BOOL, "false"),
// Common properties
list.push_back("auth.username");
list.push_back("auth.password");
property(serviceInfos::property::AUTH_USERNAME),
property(serviceInfos::property::AUTH_PASSWORD),
list.push_back("server.address");
list.push_back("server.port");
list.push_back("server.socket-factory");
property(serviceInfos::property::SERVER_ADDRESS, serviceInfos::property::FLAG_REQUIRED),
property(serviceInfos::property::SERVER_PORT, "25"),
property(serviceInfos::property::SERVER_SOCKETFACTORY),
list.push_back("timeout.factory");
property(serviceInfos::property::TIMEOUT_FACTORY)
};
return p;
}
const std::vector <serviceInfos::property> SMTPTransport::_infos::getAvailableProperties() const
{
std::vector <property> list;
const props& p = getProperties();
// SMTP-specific options
list.push_back(p.PROPERTY_OPTIONS_NEEDAUTH);
// Common properties
list.push_back(p.PROPERTY_AUTH_USERNAME);
list.push_back(p.PROPERTY_AUTH_PASSWORD);
list.push_back(p.PROPERTY_SERVER_ADDRESS);
list.push_back(p.PROPERTY_SERVER_PORT);
list.push_back(p.PROPERTY_SERVER_SOCKETFACTORY);
list.push_back(p.PROPERTY_TIMEOUT_FACTORY);
return (list);
}

View File

@ -324,6 +324,46 @@ const bool propertySet::property::getValue() const
}
}
template <>
const string propertySet::valueFromString(const string& value)
{
return value;
}
template <>
const string propertySet::valueToString(const string& value)
{
return value;
}
template <>
const bool propertySet::valueFromString(const string& value)
{
if (utility::stringUtils::toLower(value) == "true")
return true;
else
{
int val = 0;
std::istringstream iss(value);
iss >> val;
return (!iss.fail() && val != 0);
}
}
template <>
const string propertySet::valueToString(const bool& value)
{
return (value ? "true" : "false");
}
#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION

View File

@ -26,6 +26,7 @@
#include "vmime/messaging/authenticator.hpp"
#include "vmime/messaging/socket.hpp"
#include "vmime/messaging/timeoutHandler.hpp"
#include "vmime/messaging/session.hpp"
#include "vmime/messaging/imap/IMAPParser.hpp"
@ -61,11 +62,11 @@ public:
STATE_LOGOUT
};
const ProtocolStates state() const { return (m_state); }
void setState(const ProtocolStates state) { m_state = state; }
const ProtocolStates state() const;
void setState(const ProtocolStates state);
const char hierarchySeparator() const { return (m_hierarchySeparator); }
const char hierarchySeparator() const;
void send(bool tag, const string& what, bool end);
@ -74,11 +75,13 @@ public:
IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL);
const IMAPTag* getTag() const { return (m_tag); }
const IMAPParser* getParser() const { return (m_parser); }
const IMAPTag* getTag() const;
const IMAPParser* getParser() const;
const IMAPStore* getStore() const { return (m_store); }
IMAPStore* getStore() { return (m_store); }
const IMAPStore* getStore() const;
IMAPStore* getStore();
session* getSession();
private:

View File

@ -47,6 +47,7 @@ class IMAPStore : public store
{
friend class IMAPFolder;
friend class IMAPMessage;
friend class IMAPConnection;
public:
@ -101,10 +102,26 @@ private:
{
public:
const port_t getDefaultPort() const;
struct props
{
// IMAP-specific options
// (none)
// Common properties
serviceInfos::property PROPERTY_AUTH_USERNAME;
serviceInfos::property PROPERTY_AUTH_PASSWORD;
serviceInfos::property PROPERTY_SERVER_ADDRESS;
serviceInfos::property PROPERTY_SERVER_PORT;
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
};
const props& getProperties() const;
const string getPropertyPrefix() const;
const std::vector <string> getAvailableProperties() const;
const std::vector <serviceInfos::property> getAvailableProperties() const;
};
static _infos sm_infos;

View File

@ -91,10 +91,15 @@ private:
{
public:
const port_t getDefaultPort() const;
struct props
{
serviceInfos::property PROPERTY_SERVER_ROOTPATH;
};
const props& getProperties() const;
const string getPropertyPrefix() const;
const std::vector <string> getAvailableProperties() const;
const std::vector <serviceInfos::property> getAvailableProperties() const;
};
static _infos sm_infos;

View File

@ -43,6 +43,8 @@ class POP3Store : public store
friend class POP3Folder;
friend class POP3Message;
private:
public:
POP3Store(session* sess, authenticator* auth);
@ -100,10 +102,27 @@ private:
{
public:
const port_t getDefaultPort() const;
struct props
{
// POP3-specific options
serviceInfos::property PROPERTY_OPTIONS_APOP;
serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK;
// Common properties
serviceInfos::property PROPERTY_AUTH_USERNAME;
serviceInfos::property PROPERTY_AUTH_PASSWORD;
serviceInfos::property PROPERTY_SERVER_ADDRESS;
serviceInfos::property PROPERTY_SERVER_PORT;
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
};
const props& getProperties() const;
const string getPropertyPrefix() const;
const std::vector <string> getAvailableProperties() const;
const std::vector <serviceInfos::property> getAvailableProperties() const;
};
static _infos sm_infos;

View File

@ -77,10 +77,15 @@ private:
{
public:
const port_t getDefaultPort() const;
struct props
{
serviceInfos::property PROPERTY_BINPATH;
};
const props& getProperties() const;
const string getPropertyPrefix() const;
const std::vector <string> getAvailableProperties() const;
const std::vector <serviceInfos::property> getAvailableProperties() const;
};
static _infos sm_infos;

View File

@ -25,6 +25,8 @@
#include "vmime/types.hpp"
#include "vmime/messaging/session.hpp"
namespace vmime {
namespace messaging {
@ -39,22 +41,143 @@ class serviceInfos
protected:
serviceInfos() { }
serviceInfos(const serviceInfos&) { }
serviceInfos();
serviceInfos(const serviceInfos&);
private:
serviceInfos& operator=(const serviceInfos&) { return (*this); }
serviceInfos& operator=(const serviceInfos&);
public:
virtual ~serviceInfos() { }
virtual ~serviceInfos();
/** Return the default port used for the underlying protocol.
*
* @return default port number
/** A service property.
*/
virtual const port_t getDefaultPort() const = 0;
class property
{
public:
/** The common property 'server.address' which is
* the host name or the IP address of the server. */
static const property SERVER_ADDRESS;
/** The common property 'server.port' which is
* the port used to connect to the server. */
static const property SERVER_PORT;
/** The common property 'server.rootpath' which is
* the full path of the folder on the server (for
* maildir, this is the local filesystem directory). */
static const property SERVER_ROOTPATH;
/** The common property 'server.socket-factory' used
* to indicate which factory to use to instanciate
* new socket objects. */
static const property SERVER_SOCKETFACTORY;
/** The common property 'auth.username' which is the
* username used to authenticate with the server. */
static const property AUTH_USERNAME;
/** The common property 'auth.password' which is the
* password used to authenticate with the server. */
static const property AUTH_PASSWORD;
/** The common property 'timeout.factory' used to
* specify which factory to use to instanciate
* time-out handler objects. If none is specified,
* no time-out handler is used. */
static const property TIMEOUT_FACTORY;
/** Value types.
*/
enum Types
{
TYPE_INTEGER, /*< Integer number. */
TYPE_STRING, /*< Character string. */
TYPE_BOOL, /*< Boolean (true or false). */
TYPE_DEFAULT = TYPE_STRING
};
/** Property 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
to the user but can be modified. */
FLAG_DEFAULT = FLAG_NONE /*< Default flags. */
};
/** Construct a new property.
*
* @param name property name
* @param type value type
* @param defaultValue default value
* @param flags property attributes
*/
property(const string& name, const Types type, const string& defaultValue = "", const int flags = FLAG_DEFAULT);
/** Construct a new property from an existing property.
*
* @param p source property
* @param addFlags flags to add
* @param removeFlags flags to remove
*/
property(const property& p, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE);
/** Construct a new property from an existing property.
*
* @param p source property
* @param newDefaultValue new default value
* @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& operator=(const property& p);
/** Return the name of the property.
*
* @return property name
*/
const string& getName() const;
/** Return the default value of the property or
* an empty string if there is no default value.
*
* @return default value for the property
*/
const string& getDefaultValue() const;
/** Return the value type of the property.
*
* @return property value type
*/
const Types getType() const;
/** Return the attributes of the property (see
* serviceInfos::property::Types constants).
*
* @return property attributes
*/
const int getFlags() const;
private:
string m_name;
string m_defaultValue;
Types m_type;
int m_flags;
};
/** Return the property prefix used by this service.
* Use this to set/get properties in the session object.
@ -65,9 +188,36 @@ public:
/** Return a list of available properties for this service.
*
* @return list of property names
* @return list of properties
*/
virtual const std::vector <string> getAvailableProperties() const = 0;
virtual const std::vector <property> getAvailableProperties() const = 0;
/** Helper function to retrieve the value of a property.
*
* @param s session object
* @param p property to retrieve
* @throw exceptions::no_such_property if the property does not exist
* and has the flag property::FLAG_REQUIRED
* @return value of the property
*/
template <typename TYPE>
const TYPE getPropertyValue(session* s, const property& p) const
{
if (p.getFlags() & property::FLAG_REQUIRED)
return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue <TYPE>();
return s->getProperties().template getProperty <TYPE>(getPropertyPrefix() + p.getName(),
propertySet::valueFromString <TYPE>(p.getDefaultValue()));
}
/** Helper function to test if the specified property is set in
* the session object.
*
* @param s session object
* @param p property to test
* @return true if the property is set, false otherwise
*/
const bool hasProperty(session* s, const property& p) const;
};

View File

@ -79,10 +79,26 @@ private:
{
public:
const port_t getDefaultPort() const;
struct props
{
// SMTP-specific options
serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH;
// Common properties
serviceInfos::property PROPERTY_AUTH_USERNAME;
serviceInfos::property PROPERTY_AUTH_PASSWORD;
serviceInfos::property PROPERTY_SERVER_ADDRESS;
serviceInfos::property PROPERTY_SERVER_PORT;
serviceInfos::property PROPERTY_SERVER_SOCKETFACTORY;
serviceInfos::property PROPERTY_TIMEOUT_FACTORY;
};
const props& getProperties() const;
const string getPropertyPrefix() const;
const std::vector <string> getAvailableProperties() const;
const std::vector <serviceInfos::property> getAvailableProperties() const;
};
static _infos sm_infos;

View File

@ -342,6 +342,64 @@ private:
public:
template <typename TYPE>
static const TYPE valueFromString(const string& value)
{
TYPE v = TYPE();
std::istringstream iss(value);
iss >> v;
return v;
}
template <typename TYPE>
static const string valueToString(const TYPE& value)
{
std::ostringstream oss(value);
oss << value;
return oss.str();
}
#ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION
template <>
static const string valueFromString(const string& value)
{
return value;
}
template <>
static const string valueToString(const string& value)
{
return value;
}
template <>
static const bool valueFromString(const string& value)
{
if (utility::stringUtils::toLower(m_value) == "true")
return true;
else
{
int val = 0;
std::istringstream iss(m_value);
iss >> val;
return (!iss.fail() && val != 0);
}
}
template <>
static const string valueToString(const bool& value)
{
return (value ? "true" : "false");
}
#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION
/** Return the property list.
*
* @return list of properties
@ -364,6 +422,12 @@ template <> void propertySet::property::setValue(const bool& value);
template <> const string propertySet::property::getValue() const;
template <> const bool propertySet::property::getValue() const;
template <> const string propertySet::valueFromString(const string& value);
template <> const string propertySet::valueToString(const string& value);
template <> const bool propertySet::valueFromString(const string& value);
template <> const string propertySet::valueToString(const bool& value);
#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION