diff options
Diffstat (limited to 'kdecore/network/ksocketaddress.cpp')
-rw-r--r-- | kdecore/network/ksocketaddress.cpp | 957 |
1 files changed, 0 insertions, 957 deletions
diff --git a/kdecore/network/ksocketaddress.cpp b/kdecore/network/ksocketaddress.cpp deleted file mode 100644 index feaabfab5..000000000 --- a/kdecore/network/ksocketaddress.cpp +++ /dev/null @@ -1,957 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include <tqfile.h> -#include <tqobject.h> - -#include "klocale.h" -#include "ksocketaddress.h" - -#include "netsupp.h" - -using namespace KNetwork; - -#if 0 -class KIpAddress_localhostV4 : public KIpAddress -{ -public: - KIpAddress_localhostV4() - { - *m_data = htonl(0x7f000001); - m_version = 4; - } -}; - -class KIpAddress_localhostV6 : public KIpAddress -{ -public: - KIpAddress_localhostV6() - : KIpAddress(0L, 6) - { - m_data[3] = htonl(1); - } -}; -#endif - -static const char localhostV4_data[] = { 127, 0, 0, 1 }; -static const char localhostV6_data[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1 }; - -const KIpAddress KIpAddress::localhostV4(&localhostV4_data, 4); -const KIpAddress KIpAddress::localhostV6(&localhostV6_data, 6); -const KIpAddress KIpAddress::anyhostV4(0L, 4); -const KIpAddress KIpAddress::anyhostV6(0L, 6); - -// helper function to test if an IPv6 v4-mapped address is equal to its IPv4 counterpart -static bool check_v4mapped(const TQ_UINT32* v6addr, TQ_UINT32 v4addr) -{ - // check that the v6 is a v4-mapped address - if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff))) - return false; // not a v4-mapped address - - return v6addr[3] == v4addr; -} - -// copy operator -KIpAddress& KIpAddress::operator =(const KIpAddress& other) -{ - m_version = other.m_version; - if (m_version == 4 || m_version == 6) - memcpy(m_data, other.m_data, sizeof(m_data)); - return *this; -} - -// comparison -bool KIpAddress::compare(const KIpAddress& other, bool checkMapped) const -{ - if (m_version == other.m_version) - switch (m_version) - { - case 0: - // both objects are empty - return true; - - case 4: - // IPv4 address - return *m_data == *other.m_data; - - case 6: - // IPv6 address - // they are 128-bit long, that is, 16 bytes - return memcmp(m_data, other.m_data, 16) == 0; - } - - if (checkMapped) - { - // check the possibility of a v4-mapped address being compared to an IPv4 one - if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data)) - return true; - - if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data)) - return true; - } - - return false; -} - -// sets the address to the given address -bool KIpAddress::setAddress(const TQString& address) -{ - m_version = 0; - - // try to guess the address version - if (address.find(':') != -1) - { -#ifdef AF_INET6 - // guessing IPv6 - - TQ_UINT32 buf[4]; - if (inet_pton(AF_INET6, address.latin1(), buf)) - { - memcpy(m_data, buf, sizeof(m_data)); - m_version = 6; - return true; - } -#endif - - return false; - } - else - { - TQ_UINT32 buf; - if (inet_pton(AF_INET, address.latin1(), &buf)) - { - *m_data = buf; - m_version = 4; - return true; - } - - return false; - } - - return false; // can never happen! -} - -bool KIpAddress::setAddress(const char* address) -{ - return setAddress(TQString::tqfromLatin1(address)); -} - -// set from binary data -bool KIpAddress::setAddress(const void* raw, int version) -{ - // this always succeeds - // except if version is invalid - if (version != 4 && version != 6) - return false; - - m_version = version; - if (raw != 0L) - memcpy(m_data, raw, version == 4 ? 4 : 16); - else - memset(m_data, 0, 16); - - return true; -} - -// presentation form -TQString KIpAddress::toString() const -{ - char buf[sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2]; - buf[0] = '\0'; - switch (m_version) - { - case 4: - inet_ntop(AF_INET, m_data, buf, sizeof(buf) - 1); - return TQString::tqfromLatin1(buf); - - case 6: -#ifdef AF_INET6 - inet_ntop(AF_INET6, m_data, buf, sizeof(buf) - 1); -#endif - return TQString::tqfromLatin1(buf); - } - - return TQString::null; -} - -TQ_UINT32 KIpAddress::hostIPv4Addr(bool convertMapped) const -{ - TQ_UINT32 addr = IPv4Addr(convertMapped); - return ntohl(addr); -} - -/* - * An IPv6 socket address - * This is taken from RFC 2553. - */ -struct our_sockaddr_in6 -{ -# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - TQ_UINT8 sin6_len; - TQ_UINT8 sin6_family; -# else //!HAVE_STRUCT_SOCKADDR_SA_LEN - TQ_UINT16 sin6_family; -# endif - TQ_UINT16 sin6_port; /* RFC says in_port_t */ - TQ_UINT32 sin6_flowinfo; - TQ_UINT8 sin6_addr[16]; // 24 bytes up to here - TQ_UINT32 sin6_scope_id; // 28 bytes total -}; - -// useful definitions -#define MIN_SOCKADDR_LEN sizeof(TQ_UINT16) -#define SOCKADDR_IN_LEN sizeof(sockaddr_in) -#define MIN_SOCKADDR_IN6_LEN ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id)) -#define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6) -#define MIN_SOCKADDR_UN_LEN (sizeof(TQ_UINT16) + sizeof(char)) - - -class KNetwork::KSocketAddressData -{ -public: - /* - * Note: maybe this should be virtual - * But since the data is shared via the d pointer, it doesn't really matter - * what one class sees, so will the other - */ - class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress - { - public: - QMixSocketAddressRef(KSocketAddressData* d) - : KInetSocketAddress(d), KUnixSocketAddress(d) - { - } - }; - QMixSocketAddressRef ref; - - union - { - struct sockaddr *generic; - struct sockaddr_in *in; - struct our_sockaddr_in6 *in6; - struct sockaddr_un *un; - } addr; - TQ_UINT16 curlen, reallen; - - KSocketAddressData() - : ref(this) - { - addr.generic = 0L; - curlen = 0; - tqinvalidate(); - } - - ~KSocketAddressData() - { - if (addr.generic != 0L) - free(addr.generic); - } - - inline bool invalid() const - { return reallen == 0; } - - inline void tqinvalidate() - { reallen = 0; } - - void dup(const sockaddr* sa, TQ_UINT16 len, bool clear = true); - - void makeipv4() - { - short oldport = 0; - if (!invalid()) - switch (addr.generic->sa_family) - { - case AF_INET: - return; // nothing to do here -#ifdef AF_INET6 - case AF_INET6: - oldport = addr.in6->sin6_port; - break; -#endif - } - - // create new space - dup(0L, SOCKADDR_IN_LEN); - - addr.in->sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - addr.in->sin_len = SOCKADDR_IN_LEN; -#endif - addr.in->sin_port = oldport; - } - - void makeipv6() - { - short oldport = 0; - if (!invalid()) - switch (addr.generic->sa_family) - { - case AF_INET: - oldport = addr.in->sin_port; - break; - -#ifdef AF_INET6 - case AF_INET6: - return; // nothing to do here -#endif - } - - // make room - dup(0L, SOCKADDR_IN6_LEN); -#ifdef AF_INET6 - addr.in6->sin6_family = AF_INET6; -#endif -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - addr.in6->sin6_len = SOCKADDR_IN6_LEN; -#endif - addr.in6->sin6_port = oldport; - // sin6_scope_id and sin6_flowid are zero - } - -}; - -// create duplicates of -void KSocketAddressData::dup(const sockaddr* sa, TQ_UINT16 len, bool clear) -{ - if (len < MIN_SOCKADDR_LEN) - { - // certainly invalid - tqinvalidate(); - return; - } - - if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) || -#ifdef AF_INET6 - (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) || -#endif - (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN))) - { - // also invalid - tqinvalidate(); - return; - } - - // good - reallen = len; - if (len > curlen) - { - if (len < 32) - curlen = 32; // big enough for sockaddr_in and sockaddr_in6 - else - curlen = len; - addr.generic = (sockaddr*)realloc(addr.generic, curlen); - } - - if (sa != 0L) - { - memcpy(addr.generic, sa, len); // copy - - // now, normalise the data - if (addr.generic->sa_family == AF_INET) - reallen = SOCKADDR_IN_LEN; // no need to be larger -#ifdef AF_INET6 - else if (addr.generic->sa_family == AF_INET6) - { - // set the extra field (sin6_scope_id) - - // the buffer is never smaller than 32 bytes, so this is always - // allowed - if (reallen < SOCKADDR_IN6_LEN) - addr.in6->sin6_scope_id = 0; - - reallen = SOCKADDR_IN6_LEN; - } -#endif - else if (addr.generic->sa_family == AF_UNIX) - reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path); - } - else if (clear) - { - memset(addr.generic, 0, len); - addr.generic->sa_family = AF_UNSPEC; - } -} - -// default constructor -KSocketAddress::KSocketAddress() - : d(new KSocketAddressData) -{ -} - -// constructor from binary data -KSocketAddress::KSocketAddress(const sockaddr *sa, TQ_UINT16 len) - : d(new KSocketAddressData) -{ - setAddress(sa, len); -} - -KSocketAddress::KSocketAddress(const KSocketAddress& other) - : d(new(KSocketAddressData)) -{ - *this = other; -} - -KSocketAddress::KSocketAddress(KSocketAddressData *d2) - : d(d2) -{ -} - -KSocketAddress::~KSocketAddress() -{ - // prevent double-deletion, since we're already being deleted - if (d) - { - d->ref.KInetSocketAddress::d = 0L; - d->ref.KUnixSocketAddress::d = 0L; - delete d; - } -} - -KSocketAddress& KSocketAddress::operator =(const KSocketAddress& other) -{ - if (other.d && !other.d->invalid()) - d->dup(other.d->addr.generic, other.d->reallen); - else - d->tqinvalidate(); - return *this; -} - -const sockaddr* KSocketAddress::address() const -{ - if (d->invalid()) - return 0L; - return d->addr.generic; -} - -sockaddr* KSocketAddress::address() -{ - if (d->invalid()) - return 0L; - return d->addr.generic; -} - -KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, TQ_UINT16 len) -{ - if (sa != 0L && len >= MIN_SOCKADDR_LEN) - d->dup(sa, len); - else - d->tqinvalidate(); - - return *this; -} - -TQ_UINT16 KSocketAddress::length() const -{ - if (d->invalid()) - return 0; - return d->reallen; -} - -KSocketAddress& KSocketAddress::setLength(TQ_UINT16 len) -{ - d->dup((sockaddr*)0L, len, false); - - return *this; -} - -int KSocketAddress::family() const -{ - if (d->invalid()) - return AF_UNSPEC; - return d->addr.generic->sa_family; -} - -KSocketAddress& KSocketAddress::setFamily(int family) -{ - if (d->invalid()) - d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN); - d->addr.generic->sa_family = family; - - return *this; -} - -bool KSocketAddress::operator ==(const KSocketAddress& other) const -{ - // if this is invalid, it's only equal if the other one is invalid as well - if (d->invalid()) - return other.d->invalid(); - - // check the family to make sure we don't do unnecessary comparison - if (d->addr.generic->sa_family != other.d->addr.generic->sa_family) - return false; // not the same family, not equal - - // same family then - // check the ones we know already - switch (d->addr.generic->sa_family) - { - case AF_INET: - Q_ASSERT(d->reallen == SOCKADDR_IN_LEN); - Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN); - return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0; - -#ifdef AF_INET6 - case AF_INET6: - Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN); - Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN); - -# if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) - // check for the case where sin6_scope_id isn't present - if (d->reallen != other.d->reallen) - { - if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0) - return false; // not equal - if (d->reallen > other.d->reallen) - return d->addr.in6->sin6_scope_id == 0; - else - return other.d->addr.in6->sin6_scope_id == 0; - } -# endif - - return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0; -#endif - - case AF_UNIX: - Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN); - Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN); - - // do a string comparison here - return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0; - - default: - // something else we don't know about - // they are equal if and only if they are exactly equal - if (d->reallen == other.d->reallen) - return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0; - } - - return false; // not equal in any other case -} - -TQString KSocketAddress::nodeName() const -{ - if (d->invalid()) - return TQString::null; - - switch (d->addr.generic->sa_family) - { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: - - TQString scopeid("%"); - if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id) - scopeid += TQString::number(d->addr.in6->sin6_scope_id); - else - scopeid.truncate(0); - return d->ref.ipAddress().toString() + scopeid; -#else - return d->ref.ipAddress().toString(); -#endif - } - - // any other case, including AF_UNIX - return TQString::null; -} - -TQString KSocketAddress::serviceName() const -{ - if (d->invalid()) - return TQString::null; - - switch (d->addr.generic->sa_family) - { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: -#endif - return TQString::number(d->ref.port()); - - case AF_UNIX: - return d->ref.pathname(); - } - - return TQString::null; -} - -TQString KSocketAddress::toString() const -{ - if (d->invalid()) - return TQString::null; - - TQString fmt; - - if (d->addr.generic->sa_family == AF_INET) - fmt = "%1:%2"; -#ifdef AF_INET6 - else if (d->addr.generic->sa_family == AF_INET6) - fmt = "[%1]:%2"; -#endif - else if (d->addr.generic->sa_family == AF_UNIX) - return TQString::tqfromLatin1("unix:%1").arg(serviceName()); - else - return i18n("1: the unknown socket address family number", - "Unknown family %1").arg(d->addr.generic->sa_family); - - return fmt.arg(nodeName()).arg(serviceName()); -} - -KInetSocketAddress& KSocketAddress::asInet() -{ - return d->ref; -} - -KInetSocketAddress KSocketAddress::asInet() const -{ - return d->ref; -} - -KUnixSocketAddress& KSocketAddress::asUnix() -{ - return d->ref; -} - -KUnixSocketAddress KSocketAddress::asUnix() const -{ - return d->ref; -} - -int KSocketAddress::ianaFamily(int af) -{ - switch (af) - { - case AF_INET: - return 1; - -#ifdef AF_INET6 - case AF_INET6: - return 2; -#endif - - default: - return 0; - } -} - -int KSocketAddress::fromIanaFamily(int iana) -{ - switch (iana) - { - case 1: - return AF_INET; - -#ifdef AF_INET6 - case 2: - return AF_INET6; -#endif - - default: - return AF_UNSPEC; - } -} - -// default constructor -KInetSocketAddress::KInetSocketAddress() -{ -} - -// binary data constructor -KInetSocketAddress::KInetSocketAddress(const sockaddr* sa, TQ_UINT16 len) - : KSocketAddress(sa, len) -{ - if (!d->invalid()) - update(); -} - -// create from IP and port -KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, TQ_UINT16 port) -{ - setHost(host); - setPort(port); -} - -// copy constructor -KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other) - : KSocketAddress(other) -{ -} - -// special copy constructor -KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other) - : KSocketAddress(other) -{ - if (!d->invalid()) - update(); -} - -// special constructor -KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d) - : KSocketAddress(d) -{ -} - -// destructor -KInetSocketAddress::~KInetSocketAddress() -{ - /* nothing to do */ -} - -// copy operator -KInetSocketAddress& KInetSocketAddress::operator =(const KInetSocketAddress& other) -{ - KSocketAddress::operator =(other); - return *this; -} - -// IP version -int KInetSocketAddress::ipVersion() const -{ - if (d->invalid()) - return 0; - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return 4; - -#ifdef AF_INET6 - case AF_INET6: - return 6; -#endif - } - - return 0; // for all other cases -} - -KIpAddress KInetSocketAddress::ipAddress() const -{ - if (d->invalid()) - return KIpAddress(); // return an empty address as well - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return KIpAddress(&d->addr.in->sin_addr, 4); -#ifdef AF_INET6 - case AF_INET6: - return KIpAddress(&d->addr.in6->sin6_addr, 6); -#endif - } - - return KIpAddress(); // empty in all other cases -} - -KInetSocketAddress& KInetSocketAddress::setHost(const KIpAddress& ip) -{ - switch (ip.version()) - { - case 4: - makeIPv4(); - memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr)); - break; - - case 6: - makeIPv6(); - memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr)); - break; - - default: - // empty - d->tqinvalidate(); - } - - return *this; -} - -// returns the port -TQ_UINT16 KInetSocketAddress::port() const -{ - if (d->invalid()) - return 0; - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return ntohs(d->addr.in->sin_port); - -#ifdef AF_INET6 - case AF_INET6: - return ntohs(d->addr.in6->sin6_port); -#endif - } - - return 0; -} - -KInetSocketAddress& KInetSocketAddress::setPort(TQ_UINT16 port) -{ - if (d->invalid()) - makeIPv4(); - - switch (d->addr.generic->sa_family) - { - case AF_INET: - d->addr.in->sin_port = htons(port); - break; - -#ifdef AF_INET6 - case AF_INET6: - d->addr.in6->sin6_port = htons(port); - break; -#endif - - default: - d->tqinvalidate(); // setting the port on something else - } - - return *this; -} - -KInetSocketAddress& KInetSocketAddress::makeIPv4() -{ - d->makeipv4(); - return *this; -} - -KInetSocketAddress& KInetSocketAddress::makeIPv6() -{ - d->makeipv6(); - return *this; -} - -TQ_UINT32 KInetSocketAddress::flowinfo() const -{ -#ifndef AF_INET6 - return 0; -#else - - if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) - return d->addr.in6->sin6_flowinfo; - return 0; -#endif -} - -KInetSocketAddress& KInetSocketAddress::setFlowinfo(TQ_UINT32 flowinfo) -{ - makeIPv6(); // must set here - d->addr.in6->sin6_flowinfo = flowinfo; - return *this; -} - -int KInetSocketAddress::scopeId() const -{ -#ifndef AF_INET6 - return 0; -#else - - if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) - return d->addr.in6->sin6_scope_id; - return 0; -#endif -} - -KInetSocketAddress& KInetSocketAddress::setScopeId(int scopeid) -{ - makeIPv6(); // must set here - d->addr.in6->sin6_scope_id = scopeid; - return *this; -} - -void KInetSocketAddress::update() -{ - if (d->addr.generic->sa_family == AF_INET) - return; -#ifdef AF_INET6 - else if (d->addr.generic->sa_family == AF_INET6) - return; -#endif - else - d->tqinvalidate(); -} - -KUnixSocketAddress::KUnixSocketAddress() -{ -} - -KUnixSocketAddress::KUnixSocketAddress(const sockaddr* sa, TQ_UINT16 len) - : KSocketAddress(sa, len) -{ - if (!d->invalid() && d->addr.un->sun_family != AF_UNIX) - d->tqinvalidate(); -} - -KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress& other) - : KSocketAddress(other) -{ -} - -KUnixSocketAddress::KUnixSocketAddress(const TQString& pathname) -{ - setPathname(pathname); -} - -KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d) - : KSocketAddress(d) -{ -} - -KUnixSocketAddress::~KUnixSocketAddress() -{ -} - -KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other) -{ - KSocketAddress::operator =(other); - return *this; -} - -TQString KUnixSocketAddress::pathname() const -{ - if (!d->invalid() && d->addr.un->sun_family == AF_UNIX) - return TQFile::decodeName(d->addr.un->sun_path); - return TQString::null; -} - -KUnixSocketAddress& KUnixSocketAddress::setPathname(const TQString& path) -{ - d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length()); - d->addr.un->sun_family = AF_UNIX; - strcpy(d->addr.un->sun_path, TQFile::encodeName(path)); - -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - d->addr.un->sun_len = d->reallen; -#endif - - return *this; -} |