skstream
skaddress.h
00001 /**************************************************************************
00002  FreeSockets - Portable C++ classes for IP(sockets) applications. (v0.3)
00003  Copyright (C) 2012 Alistair Riddoch
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 **************************************************************************/
00020 
00028 #ifndef RGJ_FREE_ADDRESS_H_
00029 #define RGJ_FREE_ADDRESS_H_
00030 
00031 #include <skstream/sksocket.h>
00032 
00033 #include <string>
00034 
00035 struct addrinfo;
00036 
00037 // I am making this inherit from basic_socket, even though it does not
00038 // at this time appear to be a socket. This is so that it can ensure
00039 // basic_socket::startup is called in the standard way, and so that if in
00040 // future we need a custom, non blocking resolver, we can have one.
00041 
00042 class basic_address : public basic_socket {
00043 protected:
00044   struct addrinfo * _addrlist;
00045 
00046   int _type;
00047   int _protocol;
00048 
00049   basic_address(int, int);
00050 
00051   int resolve(int, const char *, const char *);
00052 
00053   // FIXME some data structures for non-getaddrinfo legacy systems
00054 public:
00055   struct addrinfo * takeAddressInfo() {
00056     struct addrinfo * t = _addrlist;
00057     _addrlist = 0;
00058     return t;
00059   }
00060 
00061   virtual ~basic_address();
00062 
00064   bool isReady() const {
00065     return _addrlist != 0;
00066   }
00067 
00068   int resolveListener(const std::string & service);
00069 
00070   int resolveConnector(const std::string & host, const std::string & service);
00071   
00072   // FIXME - perhaps we could do this like an iterator, c++11 style
00073 
00075   std::size_t size() const;
00076 
00077   class const_iterator;
00078 
00079   const_iterator begin() const;
00080   const_iterator end() const;
00081 
00083   struct addrinfo * getAddrinfo(std::size_t c) const;
00084 
00085   virtual SOCKET_TYPE getSocket() const;
00086   
00087 };
00088 
00089 class basic_address::const_iterator {
00090 private:
00091   friend class basic_address;
00092 
00093   struct addrinfo * _info;
00094 
00095   explicit const_iterator(struct addrinfo * i) : _info(i) {
00096   }
00097 
00098 public:
00099   // FIXME Add move stuff (c++11)
00100   const_iterator() : _info(0) {
00101   }
00102 
00103   const_iterator(const const_iterator & rhs) : _info(rhs._info) {
00104   }
00105 
00106   bool operator==(const const_iterator& rhs) {
00107     return _info == rhs._info;
00108   }
00109 
00110   bool operator!=(const const_iterator& rhs) {
00111     return !this->operator==(rhs);
00112   }
00113 
00114   const_iterator& operator=(const const_iterator& rhs) {
00115     _info = rhs._info;
00116     return *this;
00117   }
00118 
00119   struct addrinfo * operator*() const {
00120     return _info;
00121   }
00122 
00123   const_iterator& operator++();
00124 };
00125 
00126 inline basic_address::const_iterator basic_address::begin() const
00127 {
00128   return basic_address::const_iterator(_addrlist);
00129 }
00130 
00131 inline basic_address::const_iterator basic_address::end() const
00132 {
00133   return basic_address::const_iterator(0);
00134 }
00135 
00136 class tcp_address : public basic_address {
00137 public:
00138   tcp_address();
00139 
00140 };
00141 
00142 class ip_datagram_address : public basic_address {
00143 public:
00144   ip_datagram_address();
00145 
00146 };
00147 
00148 #endif // RGJ_FREE_SOCKET_H_