// $Id$ // // Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // 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 BSDSocketAddress inline non-template implementation */ //#include "BSDSocketAddress.ih" // Custom includes #include #include #include #define prefix_ inline //-///////////////////////////////////////////////////////////////////////////////////////////////// //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::BSDSocketAddress prefix_ struct sockaddr const * senf::BSDSocketAddress::sockaddr_p() const { return static_cast(this)->sockaddr_p(); } prefix_ short senf::BSDSocketAddress::family() const { return sockaddr_p()->sa_family; } prefix_ socklen_t senf::BSDSocketAddress::socklen() const { return len_; } prefix_ socklen_t const * senf::BSDSocketAddress::socklen_p() const { return & len_; } prefix_ void senf::BSDSocketAddress::socklen(socklen_t len) { len_ = len; } prefix_ bool senf::BSDSocketAddress::operator==(BSDSocketAddress const & other) const { return socklen()==other.socklen() && memcmp(sockaddr_p(), other.sockaddr_p(), socklen())==0; } prefix_ bool senf::BSDSocketAddress::operator<(BSDSocketAddress const & other) const { if (socklen() < other.socklen()) return true; else if (socklen() > other.socklen()) return false; else return memcmp(sockaddr_p(), other.sockaddr_p(), socklen()) < 0; } prefix_ bool senf::BSDSocketAddress::boolean_test() const { return socklen() > sizeof(short) && family() != AF_UNSPEC && unsigned(std::count(reinterpret_cast(sockaddr_p())+sizeof(short), reinterpret_cast(sockaddr_p())+socklen(), 0u)) < socklen()-2; } //-///////////////////////////////////////////////////////////////////////////////////////////////// // protected members prefix_ senf::BSDSocketAddress::BSDSocketAddress(socklen_t len, short family) : len_ (len) { ::memset(sockaddr_p(), 0u, len_); sockaddr_p()->sa_family = family; } // WARNING: THIS COPY CONSTRUCTOR IS NOT GENERALLY SAFE !!!!!! // It is only safe if: // a) source and target class are identical derived classes (e.g. Both INet4) // b) target is GenericBSDSocketAddress (sockaddr_storage). // // In these cases, the storage space available for the target is at least as large as that // available for the source ant the copy is ok. // // To ensure this behavior, the copy constructor is protected here and is made accessible only // via the corresponding derived classes. // // The same holds for the copy-assignment operator prefix_ senf::BSDSocketAddress::BSDSocketAddress(BSDSocketAddress const & other) : len_ (other.socklen()) { ::memcpy(sockaddr_p(), other.sockaddr_p(), len_); } prefix_ senf::BSDSocketAddress & senf::BSDSocketAddress::operator=(BSDSocketAddress const & other) { len_ = other.socklen(); ::memmove(sockaddr_p(), other.sockaddr_p(), len_); return *this; } prefix_ struct sockaddr * senf::BSDSocketAddress::sockaddr_p() { return static_cast(this)->sockaddr_p(); } prefix_ socklen_t * senf::BSDSocketAddress::socklen_p() { return & len_; } //-///////////////////////////////////////////////////////////////////////////////////////////////// // related template prefix_ Target & senf::sockaddr_cast(BSDSocketAddress & source) { if (source.family() != Target::addressFamily) throw std::bad_cast(); return static_cast(source); } template prefix_ Target const & senf::sockaddr_cast(BSDSocketAddress const & source) { if (source.family() != Target::addressFamily) throw std::bad_cast(); return static_cast(source); } //-///////////////////////////////////////////////////////////////////////////////////////////////// // senf::GenericBSDSocketAddress prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress() : BSDSocketAddress(sizeof(sockaddr_storage), AF_UNSPEC) {} prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress(BSDSocketAddress const & other) : BSDSocketAddress(other) {} prefix_ senf::GenericBSDSocketAddress& senf::GenericBSDSocketAddress::operator=(const BSDSocketAddress & other) { BSDSocketAddress::operator=(other); return *this; } prefix_ senf::GenericBSDSocketAddress::GenericBSDSocketAddress(const GenericBSDSocketAddress& other) : BSDSocketAddress(other) {} prefix_ senf::GenericBSDSocketAddress& senf::GenericBSDSocketAddress::operator=(const GenericBSDSocketAddress& other) { BSDSocketAddress::operator=(other); return *this; } prefix_ struct sockaddr const * senf::GenericBSDSocketAddress::sockaddr_p() const { return static_cast(static_cast(& addr_)); } prefix_ struct sockaddr * senf::GenericBSDSocketAddress::sockaddr_p() { return static_cast(static_cast(& addr_)); } //-///////////////////////////////////////////////////////////////////////////////////////////////// #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: