Skip to content
Snippets Groups Projects
Commit 8ee8c61c authored by g0dil's avatar g0dil
Browse files

Merged revisions 570-575,577-578 via svnmerge from

https://svn.berlios.de/svnroot/repos/senf/branches/socket-cleanup

........
  r573 | g0dil | 2007-12-18 12:15:23 +0100 (Tue, 18 Dec 2007) | 6 lines
  
  Socket: Replace 'SocketProtocol::body()' member with 'fh()' and 'fd()' members
  Socket: Rename ConvertibleString to StreamableString and use 'operator<<' instead of 'operator='
  Socket: some minor documentation clarifications
  Socket/Protocols/UN: Removed unneeded UNAddress
  Socket/Protocols/UN: Fixed UNSocketAddress to adhere to the GenericAddressingPolicy requirements
........
  r577 | g0dil | 2007-12-18 13:08:27 +0100 (Tue, 18 Dec 2007) | 1 line
  
  Socket/Protocols/UN: Add all_includes.hh to svn:ignore
........
parent fbf498f7
No related branches found
No related tags found
No related merge requests found
Showing
with 215 additions and 351 deletions
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief UNAddress non-inline non-template implementation */
#include "UNAddress.hh"
//#include "UNAddress.ih"
// Custom includes
//#include "UNAddress.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::UNAddress::UNAddress()
//:path("")
{
path = "";
}
prefix_ senf::UNAddress::UNAddress(std::string p)
{
path = p;
}
prefix_ senf::UNAddress::UNAddress senf::UNAddress::fromString(std::string & s)
{
return senf::UNAddress::UNAddress(s);
}
prefix_ std::string senf::UNAddress::pathString()
const
{
return path;
}
prefix_ senf::UNAddress::UNAddress senf::UNAddress::clone()
{
senf::UNAddress::UNAddress local_addr = senf::UNAddress::UNAddress(pathString());
return local_addr;
}
prefix_ std::ostream & senf::operator<<(std::ostream & os, UNAddress const & addr)
{
os << addr.pathString();
return os;
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "UNAddress.mpp"
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief UNAddress public header */
#ifndef HH_UNAddress_
#define HH_UNAddress_ 1
// Custom includes
#include <string>
#include <boost/operators.hpp>
#include "../../../Utils/safe_bool.hh"
//#include "UNAddress.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
/** \brief Unix domain address
UNAddress represents a simple unix domain address which is given by a path to a socket.
It is modelled as a boost::filesystem::path.
\ingroup addr_group
*/
class UNAddress
: public comparable_safe_bool<UNAddress>
{
public:
UNAddress(); ///< Construct an empty address
explicit UNAddress(std::string);///< Construct an address constant from given path
static UNAddress fromString(std::string & s); ///< Convert string to address by interpreting the string as path
UNAddress clone(); ///< Clone object
std::string pathString() const; ///< Return the path of the address as string
/** \brief Base-class for UNAddress exceptions */
struct AddressException : public std::exception {};
private:
std::string path;
};
std::ostream & operator<<(std::ostream & os, UNAddress const & addr);
}
///////////////////////////////hh.e////////////////////////////////////////
//#include "UNAddress.cci"
//#include "UNAddress.ct"
//#include "UNAddress.cti"
#endif
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum NETwork research (NET)
// David Wagner <david.wagner@fokus.fraunhofer.de>
//
// 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.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
\brief UNAddress.test unit tests */
//#include "UNAddress.test.hh"
//#include "UNAddress.test.ih"
// Custom includes
#include "UNAddress.hh"
#include <boost/filesystem/path.hpp>
#include "../../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
#include <iostream>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
BOOST_AUTO_UNIT_TEST(unAddress)
{
// TODO: muss wieder rein.
// std::string testS = "/tmp/senfTestSocket";
// boost::filesystem::path testp = boost::filesystem::path(testS);
// senf::UNAddress addr1 = senf::UNAddress::fromString(testS);
// senf::UNAddress addr2 = senf::UNAddress::fromPath(testp);
// BOOST_CHECK( testS == addr1.pathString());
// BOOST_CHECK( testS == addr2.pathString());
}
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
// Local Variables:
// mode: c++
// fill-column: 100
// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
// End:
...@@ -30,55 +30,70 @@ ...@@ -30,55 +30,70 @@
#define prefix_ #define prefix_
///////////////////////////////cc.p//////////////////////////////////////// ///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::UNSocketAddress::UNSocketAddress()
{}
prefix_ senf::UNSocketAddress::UNSocketAddress(std::string p) prefix_ senf::UNSocketAddress::UNSocketAddress(std::string p)
{ {
sockAddr.sun_family = AF_UNIX; clear();
strcpy(sockAddr.sun_path, p.c_str()); ::strncpy(addr_.sun_path, p.c_str(), sizeof(addr_.sun_path));
addr_.sun_path[sizeof(addr_.sun_path)-1] = 0;
} }
prefix_ senf::UNSocketAddress fromString(std::string s) { prefix_ senf::UNSocketAddress fromString(std::string s)
{
return senf::UNSocketAddress::UNSocketAddress(s); return senf::UNSocketAddress::UNSocketAddress(s);
} }
prefix_ bool senf::UNSocketAddress::operator==(UNSocketAddress const & other)
const
{
return path() == other.path();
}
prefix_ std::string senf::UNSocketAddress::path() prefix_ std::string senf::UNSocketAddress::path()
const const
{ {
return std::string(sockAddr.sun_path); return std::string(addr_.sun_path);
} }
prefix_ sockaddr_un senf::UNSocketAddress::sockaddr() prefix_ bool senf::UNSocketAddress::boolean_test()
const
{ {
struct sockaddr_un out; return addr_.sun_path[0] != 0;
out.sun_family = sockAddr.sun_family;
strncpy(out.sun_path, sockAddr.sun_path, sizeof( out.sun_path));
return out;
} }
prefix_ sockaddr * senf::UNSocketAddress::sockaddr_p() prefix_ void senf::UNSocketAddress::clear()
{ {
return reinterpret_cast <struct sockaddr *> (&sockAddr); ::memset(&addr_, 0, sizeof(addr_));
addr_.sun_family = AF_UNIX;
} }
prefix_ sockaddr * senf::UNSocketAddress::sockaddr_p()
{
return reinterpret_cast <struct sockaddr *> (&addr_);
}
prefix_ sockaddr const * senf::UNSocketAddress::sockaddr_p() prefix_ sockaddr const * senf::UNSocketAddress::sockaddr_p()
const const
{ {
return reinterpret_cast <struct sockaddr const *> (&sockAddr); return reinterpret_cast <struct sockaddr const *> (&addr_);
} }
prefix_ unsigned senf::UNSocketAddress::sockaddr_len() prefix_ unsigned senf::UNSocketAddress::sockaddr_len()
const const
{ {
return sizeof(sockAddr); return sizeof(addr_);
} }
prefix_ std::ostream & operator<<(std::ostream & os, senf::UNSocketAddress::UNSocketAddress const & addr){ prefix_ std::ostream & operator<<(std::ostream & os,
senf::UNSocketAddress::UNSocketAddress const & addr)
{
os << addr.path(); os << addr.path();
return os; return os;
} }
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
//#include "UNAddressing.mpp" //#include "UNAddressing.mpp"
......
...@@ -36,11 +36,12 @@ ...@@ -36,11 +36,12 @@
#include "../../../Socket/CommunicationPolicy.hh" #include "../../../Socket/CommunicationPolicy.hh"
#include "../../../Socket/Protocols/GenericAddressingPolicy.hh" #include "../../../Socket/Protocols/GenericAddressingPolicy.hh"
#include "../../../Utils/safe_bool.hh" #include "../../../Utils/safe_bool.hh"
#include "UNAddress.hh"
//#include "UNAddressing.mpp" //#include "UNAddressing.mpp"
///////////////////////////////hh.p//////////////////////////////////////// ///////////////////////////////hh.p////////////////////////////////////////
namespace senf { namespace senf {
/** \brief Unix domain socket address /** \brief Unix domain socket address
UNSocketAddress wraps the standard sockaddr_un datatype. It provides simple accessor methods UNSocketAddress wraps the standard sockaddr_un datatype. It provides simple accessor methods
...@@ -49,26 +50,37 @@ namespace senf { ...@@ -49,26 +50,37 @@ namespace senf {
\implementation This implementation is based on sockaddr_un. \implementation This implementation is based on sockaddr_un.
\ingroup addr_group \ingroup addr_group
\fixme Why both std::string constructor and from_string member ?
*/ */
class UNSocketAddress class UNSocketAddress
: public comparable_safe_bool<UNSocketAddress> : public comparable_safe_bool<UNSocketAddress>
{ {
public: public:
UNSocketAddress();
//UNSocketAddress();
explicit UNSocketAddress(std::string p); explicit UNSocketAddress(std::string p);
///< Construct an address constant from given path ///< Construct an address constant from given path
static UNSocketAddress from_string(std::string const s); ///< Create UNSocketAddress from string static UNSocketAddress from_string(std::string const s);
std::string path() const ; ///< Return path as string ///< Create UNSocketAddress from string
struct sockaddr_un sockaddr();
bool operator==(UNSocketAddress const & other) const;
///< Compare UNSocketAddress for equality
std::string path() const ; ///< Return path as string
bool boolean_test() const; ///< \c true, if address is not empty
void clear(); ///< Clear address
struct sockaddr * sockaddr_p() ; struct sockaddr * sockaddr_p() ;
struct sockaddr const * sockaddr_p() const; struct sockaddr const * sockaddr_p() const;
unsigned sockaddr_len() const; unsigned sockaddr_len() const;
private: private:
struct sockaddr_un sockAddr; struct sockaddr_un addr_;
}; };
/** \brief Write path os /** \brief Write path to os
\related UNSocketAddress \related UNSocketAddress
*/ */
...@@ -100,7 +112,10 @@ namespace senf { ...@@ -100,7 +112,10 @@ namespace senf {
using GenericAddressingPolicy<UNSocketAddress>::connect; using GenericAddressingPolicy<UNSocketAddress>::connect;
using GenericAddressingPolicy<UNSocketAddress>::bind; using GenericAddressingPolicy<UNSocketAddress>::bind;
}; };
///@}
} }
///////////////////////////////hh.e//////////////////////////////////////// ///////////////////////////////hh.e////////////////////////////////////////
//#include "UNAddressing.cci" //#include "UNAddressing.cci"
//#include "UNAddressing.ct" //#include "UNAddressing.ct"
......
...@@ -40,7 +40,7 @@ prefix_ void senf::UNDatagramSocketProtocol::init_client() const ...@@ -40,7 +40,7 @@ prefix_ void senf::UNDatagramSocketProtocol::init_client() const
int sock = ::socket(PF_UNIX,SOCK_DGRAM,0); int sock = ::socket(PF_UNIX,SOCK_DGRAM,0);
if (sock < 0) if (sock < 0)
throwErrno(); throwErrno();
body().fd(sock); fd(sock);
} }
prefix_ void senf::UNDatagramSocketProtocol::init_client(UNSocketAddress const & address) const prefix_ void senf::UNDatagramSocketProtocol::init_client(UNSocketAddress const & address) const
......
...@@ -64,11 +64,11 @@ namespace senf { ...@@ -64,11 +64,11 @@ namespace senf {
\par Address Type: \par Address Type:
UNAddress UNAddress
UNDatagramSocketProtocol provides an datagram protocol socket based on the unix domain addressing. UNDatagramSocketProtocol provides an datagram protocol socket based on the unix domain
addressing.
This class is utilized as the protocol class of the ProtocolClientSocketHandle
via the Socket Handle typedefs above.
This class is utilized as the protocol class of the ProtocolClientSocketHandle via the
Socket Handle typedefs above.
*/ */
class UNDatagramSocketProtocol class UNDatagramSocketProtocol
: public ConcreteSocketProtocol<UNDatagramSocket_Policy>, : public ConcreteSocketProtocol<UNDatagramSocket_Policy>,
...@@ -106,6 +106,8 @@ namespace senf { ...@@ -106,6 +106,8 @@ namespace senf {
typedef ProtocolClientSocketHandle<UNDatagramSocketProtocol> UNDatagramClientSocketHandle; typedef ProtocolClientSocketHandle<UNDatagramSocketProtocol> UNDatagramClientSocketHandle;
///@}
} }
///////////////////////////////hh.e//////////////////////////////////////// ///////////////////////////////hh.e////////////////////////////////////////
//#include "UNDatagramSocketHandle.cci" //#include "UNDatagramSocketHandle.cci"
......
...@@ -38,7 +38,7 @@ prefix_ unsigned senf::UNProtocol::available() ...@@ -38,7 +38,7 @@ prefix_ unsigned senf::UNProtocol::available()
const const
{ {
int n; int n;
if (::ioctl(body().fd(),SIOCINQ,&n) < 0) if (::ioctl(fd(),SIOCINQ,&n) < 0)
throwErrno(); throwErrno();
return n; return n;
} }
...@@ -52,14 +52,14 @@ prefix_ bool senf::UNProtocol::eof() ...@@ -52,14 +52,14 @@ prefix_ bool senf::UNProtocol::eof()
prefix_ void senf::UNProtocol::connect(UNSocketAddress const & address) prefix_ void senf::UNProtocol::connect(UNSocketAddress const & address)
const const
{ {
if(::connect(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0) if(::connect(fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
throwErrno(); throwErrno();
} }
prefix_ void senf::UNProtocol::bind(UNSocketAddress const & address) prefix_ void senf::UNProtocol::bind(UNSocketAddress const & address)
const const
{ {
if(::bind(body().fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0) if(::bind(fd(), address.sockaddr_p(), sizeof(sockaddr_un)) < 0)
throwErrno(); throwErrno();
} }
...@@ -85,27 +85,35 @@ prefix_ void senf::UNProtocol::terminate() ...@@ -85,27 +85,35 @@ prefix_ void senf::UNProtocol::terminate()
prefix_ void senf::UNProtocol::check_and_unlink() prefix_ void senf::UNProtocol::check_and_unlink()
const const
{ {
// struct sockaddr_un test; typedef ClientSocketHandle<MakeSocketPolicy<UNAddressingPolicy>::policy> UNSocketHandle;
// socklen_t len; try {
// memset( (char*)&test, 0xff, sizeof( test)); UNSocketAddress una (static_socket_cast<UNSocketHandle>(fh()).local());
// int fd = inputSocket.fd() ; ::unlink(una.path().c_str());
//// printf( "fd: %d\n", fd); }
// catch (SystemException & e) {
// int r = getsockname( fd, (struct sockaddr *)&test, &len);
// if( r < 0){
// perror( "bla:");
// }
// else{
// printf( "name: %d %d %s\n", r, len , test.sun_path);
// unsigned char *p = (unsigned char*) &test;for( r=0; r< len; r++) printf( "%2.2x ", (int)(p[r])); printf ("\n");
// }
struct sockaddr_un test;
socklen_t len = sizeof( test);
int r = ::getsockname( body().fd(), (struct sockaddr *)&test, &len);
if( r == 0 && ::strlen(test.sun_path) > 0){
::unlink( test.sun_path);
} }
} }
// // struct sockaddr_un test;
// // socklen_t len;
// // memset( (char*)&test, 0xff, sizeof( test));
// // int fd = inputSocket.fd() ;
// //// printf( "fd: %d\n", fd);
// //
// // int r = getsockname( fd, (struct sockaddr *)&test, &len);
// // if( r < 0){
// // perror( "bla:");
// // }
// // else{
// // printf( "name: %d %d %s\n", r, len , test.sun_path);
// // unsigned char *p = (unsigned char*) &test;for( r=0; r< len; r++) printf( "%2.2x ", (int)(p[r])); printf ("\n");
// // }
// struct sockaddr_un test;
// socklen_t len = sizeof( test);
// int r = ::getsockname(fd(), (struct sockaddr *)&test, &len);
// if( r == 0 && ::strlen(test.sun_path) > 0){
// ::unlink( test.sun_path);
// }
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
......
#include "UNAddress.hh"
#include "UNAddressing.hh"
#include "UNDatagramSocketHandle.hh"
#include "UNProtocol.hh"
...@@ -54,11 +54,11 @@ prefix_ bool senf::SocketBody::v_eof() ...@@ -54,11 +54,11 @@ prefix_ bool senf::SocketBody::v_eof()
prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod) prefix_ void senf::SocketBody::state(SocketStateMap & map, unsigned lod)
{ {
map["file.handle"] = fd(); map["file.handle"] << fd();
map["file.refcount"] = refcount(); map["file.refcount"] << refcount();
map["socket.server"] = isServer(); map["socket.server"] << isServer();
map["socket.protocol"] = prettyName(typeid(protocol())); map["socket.protocol"] << prettyName(typeid(protocol()));
map["socket.policy"] = prettyName(typeid(protocol().policy())); map["socket.policy"] << prettyName(typeid(protocol().policy()));
protocol().state(map,lod); protocol().state(map,lod);
} }
......
...@@ -61,14 +61,12 @@ prefix_ bool senf::SocketBody::isServer() ...@@ -61,14 +61,12 @@ prefix_ bool senf::SocketBody::isServer()
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// senf::detail::ConvertibleString // senf::detail::StreamableString
prefix_ senf::detail::ConvertibleString::ConvertibleString() prefix_ senf::detail::StreamableString & senf::detail::StreamableString::operator<<(bool v)
{} {
return (*this) << std::string(v ? "true" : "false");
prefix_ senf::detail::ConvertibleString::ConvertibleString(bool v) }
: std::string(v ? "true" : "false")
{}
///////////////////////////////cci.e/////////////////////////////////////// ///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_ #undef prefix_
......
...@@ -32,13 +32,16 @@ ...@@ -32,13 +32,16 @@
#define prefix_ #define prefix_
///////////////////////////////ct.p//////////////////////////////////////// ///////////////////////////////ct.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::detail::StreamableString
template <class T> template <class T>
prefix_ senf::detail::ConvertibleString & prefix_ senf::detail::StreamableString &
senf::detail::ConvertibleString::operator+=(ConvertibleString const & other) senf::detail::StreamableString::operator<<(T const & other)
{ {
if (!empty()) if (!empty())
this->std::string::operator+=(", "); (*this) += ", ";
this->std::string::operator+=(other); (*this) += boost::lexical_cast<std::string>(other);
return *this; return *this;
} }
......
...@@ -169,7 +169,7 @@ prefix_ void senf::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsig ...@@ -169,7 +169,7 @@ prefix_ void senf::SocketHandle<SocketPolicy>::state(SocketStateMap & map, unsig
// automatically include the SocketPolicy template parameter in // automatically include the SocketPolicy template parameter in
// the type name and therefore show the \e static policy of the // the type name and therefore show the \e static policy of the
// socket handle. // socket handle.
map["handle"] = prettyName(typeid(*this)); map["handle"] << prettyName(typeid(*this));
body().state(map,lod); body().state(map,lod);
} }
...@@ -181,14 +181,6 @@ prefix_ std::string senf::SocketHandle<SocketPolicy>::dumpState(unsigned lod) ...@@ -181,14 +181,6 @@ prefix_ std::string senf::SocketHandle<SocketPolicy>::dumpState(unsigned lod)
return detail::dumpState(map); return detail::dumpState(map);
} }
///////////////////////////////////////////////////////////////////////////
// senf::detail::ConvertibleString
template <class T>
prefix_ senf::detail::ConvertibleString::ConvertibleString(T const & other)
: std::string(boost::lexical_cast<std::string>(other))
{}
///////////////////////////////cti.e/////////////////////////////////////// ///////////////////////////////cti.e///////////////////////////////////////
#undef prefix_ #undef prefix_
......
...@@ -126,8 +126,8 @@ namespace senf { ...@@ -126,8 +126,8 @@ namespace senf {
\param map string to string mapping to be filled with \param map string to string mapping to be filled with
state information state information
\param lod level of detail requested. The interpretation \param lod level of detail requested. The
of this value is protocol specific interpretation of this value is protocol specific
\implementation This member will be re-implemented in \implementation This member will be re-implemented in
every derived class. This is very important since every derived class. This is very important since
...@@ -139,9 +139,9 @@ namespace senf { ...@@ -139,9 +139,9 @@ namespace senf {
/**< Formats the complete state map value and returns it as /**< Formats the complete state map value and returns it as
a single multi-line string. a single multi-line string.
param lod level of detail requested. The interpretation \param lod level of detail requested. The
of this value is protocol specific interpretation of this value is protocol specific
\implementation This member will be re-implemented in \implementation This member will be re-implemented in
every derived class. See the state() every derived class. See the state()
documentation. */ documentation. */
...@@ -169,8 +169,7 @@ namespace senf { ...@@ -169,8 +169,7 @@ namespace senf {
\param isChecked has to be \c true \param isChecked has to be \c true
\todo Answer, why the heck I need the \c isChecked \todo Answer, why the heck I need the \c isChecked
parameter ?? parameter ?? */
*/
SocketBody & body(); ///< Access socket body SocketBody & body(); ///< Access socket body
/**< This member replaces the corresponding FileHandle /**< This member replaces the corresponding FileHandle
......
...@@ -44,8 +44,8 @@ namespace senf { ...@@ -44,8 +44,8 @@ namespace senf {
/** \brief String supporting automatic type conversion /** \brief String supporting automatic type conversion
The ConvertibleString class is used to simplify creating a text representation of The StreamableString class is used to simplify creating a text representation of
arbitrary values. ConvertibleString is an ordinary string with an additional constructor arbitrary values. StreamableString is an ordinary string with an additional constructor
which allows constructing the string from any arbitrary, streamable type. which allows constructing the string from any arbitrary, streamable type.
\note It is generally not advisable to derive from the standard library container \note It is generally not advisable to derive from the standard library container
...@@ -53,36 +53,30 @@ namespace senf { ...@@ -53,36 +53,30 @@ namespace senf {
additional functionality is added. It is absolutely safe to convert the derived class additional functionality is added. It is absolutely safe to convert the derived class
back to the base type. back to the base type.
*/ */
class ConvertibleString : public std::string class StreamableString : public std::string
{ {
public: public:
ConvertibleString(); using std::string::operator=;
ConvertibleString(bool v); ///< Bool conversion constructor
/**< The bool conversion is defined explicitly to use a
specialized representation (the strings 'true' and
'false') */
template <class T>
ConvertibleString(T const & other);
///< Conversion constructor
/**< This constructor will assign the string from any
arbitrary type. It will use boost::lexical_cast to
convert the argument to its string representation. */
template <class T> template <class T>
ConvertibleString & operator+= (ConvertibleString const & other); StreamableString & operator<<(T const & other);
///< Add additional values with separator ///< Value assigment
/**< This operator facilitates the representation of /**< This operator will assign the string from any
multiple values in a single string. Each value is first arbitrary type. It will use boost::lexical_cast to
converted to a string (using the type conversion convert the argument to its string representation.
machinery of C++ and the ConvertibleString conversion
constructors). It is then appended to the current string If the string is non-empty, an additional separating
with ', ' as a separator (if the current string is comma is added to the string. */
non-empty). */
StreamableString & operator<<(bool v); ///< Bool assignment
/**< The bool assignment is defined explicitly to use a
specialized representation (the strings 'true' and
'false'). */
}; };
} }
typedef std::map< std::string, detail::ConvertibleString > SocketStateMap; typedef std::map< std::string, detail::StreamableString > SocketStateMap;
namespace detail { namespace detail {
/** \brief Helper to convert SocketStateMap to multiline string representation /** \brief Helper to convert SocketStateMap to multiline string representation
......
...@@ -41,8 +41,13 @@ checkBaseOf(SocketPolicyBase const & other) ...@@ -41,8 +41,13 @@ checkBaseOf(SocketPolicyBase const & other)
// check, wether each policy of other is (dynamically!) convertible // check, wether each policy of other is (dynamically!) convertible
// to the corresponding (static) policy of this class. Throws // to the corresponding (static) policy of this class. Throws
// std::bad_cast on failure // std::bad_cast on failure
# define SP_CheckPolicy(x1,x2,SomePolicy) (void) dynamic_cast<BOOST_PP_CAT(SomePolicy,_) const &>(other.BOOST_PP_CAT(the,SomePolicy)());
# define SP_CheckPolicy(x1,x2,SomePolicy) \
(void) dynamic_cast<BOOST_PP_CAT(SomePolicy,_) const &>( \
other.BOOST_PP_CAT(the,SomePolicy)());
BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SENF_SOCKET_POLICIES ) BOOST_PP_SEQ_FOR_EACH( SP_CheckPolicy, , SENF_SOCKET_POLICIES )
# undef SP_CheckPolicy # undef SP_CheckPolicy
} }
......
...@@ -505,10 +505,15 @@ namespace senf { ...@@ -505,10 +505,15 @@ namespace senf {
{ {
/** \brief Check dynamic policy compatibility /** \brief Check dynamic policy compatibility
This method will check the socket policy \a other against this policy. It will check, This check will validate, that a socket with \a other as it's policy is convertible to a
whether \a other is a base policy (or the same) of this policy. This check is done socket with the current SocketPolicy as it's policy. This is true, if for each policy
against the \e dynamic type of \a other using RTTI. It will throw \c std::bad_cast, if axis, the policy class of that axis as defined in the \a other policy is convertible to
the policy is not compatible. the policy class of that same axis in the current SocketPolicy instance (as is defined
by the template arguments). This again is true, if the \a other policy class is derived
from (or is the same as) the policy class taken from the current SocketPolicy instance.
In other words, this call checks, that the current SocketPolicy (as defined via the
template arguments) is more generic than the \a other socket policy.
\param[in] other SocketPolicy to check \param[in] other SocketPolicy to check
\throws std::bad_cast if \a other is not a compatible policy \throws std::bad_cast if \a other is not a compatible policy
......
...@@ -32,6 +32,28 @@ ...@@ -32,6 +32,28 @@
#define prefix_ inline #define prefix_ inline
///////////////////////////////cci.p/////////////////////////////////////// ///////////////////////////////cci.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::SocketProtocol
prefix_ senf::FileHandle senf::SocketProtocol::fh()
const
{
return body().handle();
}
prefix_ int senf::SocketProtocol::fd()
const
{
return body().fd();
}
prefix_ void senf::SocketProtocol::fd(int fd)
const
{
BOOST_ASSERT(! body().valid());
body().fd(fd);
}
prefix_ senf::SocketProtocol::SocketProtocol() prefix_ senf::SocketProtocol::SocketProtocol()
: body_(0) : body_(0)
{} {}
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#define prefix_ inline #define prefix_ inline
///////////////////////////////cti.p/////////////////////////////////////// ///////////////////////////////cti.p///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// senf::ConcreteSocketProtocol<SocketPolicy>
template <class SocketPolicy> template <class SocketPolicy>
prefix_ senf::ConcreteSocketProtocol<SocketPolicy>::~ConcreteSocketProtocol() prefix_ senf::ConcreteSocketProtocol<SocketPolicy>::~ConcreteSocketProtocol()
{} {}
......
...@@ -147,11 +147,6 @@ namespace senf { ...@@ -147,11 +147,6 @@ namespace senf {
///@} ///@}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
SocketBody & body() const; ///< Access the socket body
/**< \todo we don't need body(), we should better provide a
handle() member which will return a simple FIleHandle
object (we cannot return some other derived class since
we don't know the Protocol or Policy at this point) */
virtual SocketPolicyBase const & policy() const = 0; virtual SocketPolicyBase const & policy() const = 0;
///< Access the policy instance ///< Access the policy instance
...@@ -165,15 +160,25 @@ namespace senf { ...@@ -165,15 +160,25 @@ namespace senf {
\attention This member must be implemented in every \e \attention This member must be implemented in every \e
leaf protocol class to return a new instance of the leaf protocol class to return a new instance of the
appropriate type. */ appropriate type. */
virtual unsigned available() const = 0; virtual unsigned available() const = 0;
///< Return number of bytes available for reading without ///< Return number of bytes available for reading without
///< blocking ///< blocking
/**< This member will check in a (very, sigh) protocol /**< This member will check in a (very, sigh) protocol
dependent way, how many bytes are guaranteed to be dependent way, how many bytes may be read from a socket
readable from the socket without blocking even if the in a single (non-blocking) read operation. If the
socket is blocking. If the socket does not support socket does not support reading (viz. NotReadablePolicy
reading (viz. NotReadablePolicy is set), this member is set), this member should always return \c 0.
should always return \c 0.*/
Depending on the protocol, it may not be possible to
return a good value. In this case, an upper bound may
be returned (e.g.: When reading from a socket which
returns ethernet frames, returning 1500 from
available() is ok). However, this should only be done
as a last resort. Also beware, that this number should
not be to large since the socket layer will always need
to allocate that number of bytes for the data to be
read. */
virtual bool eof() const = 0; ///< Check for end-of-file condition virtual bool eof() const = 0; ///< Check for end-of-file condition
/**< This is another check which (like available()) is /**< This is another check which (like available()) is
...@@ -186,12 +191,13 @@ namespace senf { ...@@ -186,12 +191,13 @@ namespace senf {
/**< This override will automatically \c shutdown() the /**< This override will automatically \c shutdown() the
socket whenever it is closed. socket whenever it is closed.
\throws senf::SystemException */ \throws senf::SystemException */
virtual void terminate() const; ///< Forcibly close socket virtual void terminate() const; ///< Forcibly close socket
/**< This override will automatically \c shutdown() the /**< This override will automatically \c shutdown() the
socket whenever it is called. Additionally it will socket whenever it is called. Additionally it will
disable SO_LINGER to ensure, that v_terminate will not disable SO_LINGER to ensure, that v_terminate will not
block. Like the overriden method, this member will ignore block. Like the overriden method, this member will ignore
failures and will never throw. It therefore safe to be failures and will never throw. It is therefore safe to be
called from a destructor. */ called from a destructor. */
virtual void state(SocketStateMap & map, unsigned lod) const; virtual void state(SocketStateMap & map, unsigned lod) const;
...@@ -221,23 +227,43 @@ namespace senf { ...@@ -221,23 +227,43 @@ namespace senf {
assigning non-string values to the map: assigning non-string values to the map:
\code \code
map["socket.protocol.ip.address"] = peer(); map["socket.protocol.ip.address"] << peer();
map["socket.protocol.tcp.backlog"] = backlog(); map["socket.protocol.tcp.backlog"] << backlog();
\endcode \endcode
This will work even if peer() returns an ip-address This will work even if peer() returns an ip-address
object or backlog() returns an integer. The values are object or backlog() returns an integer. The values are
automatically converted to their string representation. automatically converted to their string representation.
The operator "+=" also has been reimplemented to Additionally, if the slot the date is written to is not
simplify adding multiple values to a single entry: It empty, the <tt>\<\<</tt> operator will add add a comma
will automatically add a ", " separator if the string as separator. */
is non-empty. */
protected: protected:
FileHandle fh() const; ///< Get a FileHandle for this instance
/**< This member will re turn a FileHandle instance for this
protocol instance. You may cast this FileHandle
instance to a ClientSocketHandle / ServerSocketHandle
as long as you know some of the socket policy using
static_socket_cast or dynamic_socket_cast */
int fd() const; ///< Get file descriptor
/**< Returns the file descriptor this protocol instance
references. This is the same as <tt>fh().fd()</tt> but
is implemented here since it is needed so often. */
void fd(int) const; ///< Initialize file descriptor
/**< Assigns the file descriptor to the file handle, this
protocol instance references. Only valid, if the file
handle has not yet been assigned any descriptor (To
change the file descriptor association later, use \c
::dup2()). */
private: private:
// backpointer to owning SocketBody instance // backpointer to owning SocketBody instance
SocketBody & body() const;
SocketBody * body_; SocketBody * body_;
friend class SocketBody; friend class SocketBody;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment