src/Network/Address.hh
changeset 378 5589abf5e61b
parent 284 27ce69fd1e06
child 380 d193dd1d8a7e
--- a/src/Network/Address.hh	Mon Dec 15 16:41:00 2008 +0000
+++ b/src/Network/Address.hh	Mon Dec 15 23:56:42 2008 +0000
@@ -1,16 +1,159 @@
 #ifndef NETWORK_ADDRESS_HH
 #define NETWORK_ADDRESS_HH
 
-#include <ClanLib/Network/Socket/ip_address.h>
+#include "../Error.hh"
+
+/*
+ * Platform-specific includes
+ */
+#ifndef WIN32
+    // linux
+    #include <sys/types.h>
+    #include <sys/socket.h>
+    #include <netdb.h>
+#else
+    #error "This network code won't compile on win32 :)"
+#endif
+
+#include <string>
+
+// assume...
+#if INET6_ADDRSTRLEN < INET_ADDRSTRLEN
+    #error INET6_ADDRSTRLEN is smaller than INET_ADDRSTRLEN
+#endif
+
+/**
+ * Length of a network address
+ */
+const socklen_t NETWORK_ADDRESS_LENGTH = INET6_ADDRSTRLEN;
 
 /**
  * We use ClanLib's IPAddress API, but with our own name
  */ 
-typedef CL_IPAddress NetworkAddress;
+class NetworkAddress {
+    private:
+        /**
+         * Our human-readable hostname
+         */
+        std::string hostname;
+
+        /**
+         * Our human-readable service
+         */
+        std::string service;
+
+        /**
+         * Our machine-readable address and its length
+         */
+        sockaddr_storage address;
+        socklen_t address_length;
+
+    public:
+        /**
+         * Construct an empty NetworkAddress
+         */
+        NetworkAddress (void);
+
+        /**
+         * Construct a NetworkAddress with a NULL hostname, and a specific service
+         */
+        NetworkAddress (std::string service);
+
+        /**
+         * Construct a NetworkAddress on a specific hostname and service
+         */
+        NetworkAddress (std::string hostname, std::string service);
+        
+        /**
+         * Construct a NetworkAddress from a machine-readable address of the given length
+         */
+        NetworkAddress (const sockaddr *addr, socklen_t len);
+   
+    public:    
+        /**
+         * Get a addrinfo* for this address using the given family/type/protocol/flags.
+         *
+         * Remember to free the returned pointer using freeaddrinfo() after use.
+         *
+         * @param family the socket family for hints.ai_family
+         * @param socktype the socket type for hints.ai_socktype
+         * @param protoocl the socket protocol for hints.ai_protocol
+         * @param flags the flags for hints.ai_flags
+         * @return linked list of addrinfo's
+         * @throw NetworkAddressError if resolving this address fails
+         */
+        addrinfo* get_addrinfo (int family, int socktype, int protocol = 0, int flags = 0) const;
+
+        /**
+         * Get a sockaddr* for this address. This is only valid for NetworkAddress's which have had set_sockaddr called
+         * on them.
+         *
+         * @param len_ref updated to the sockaddr length
+         * @return borrowed sockaddr pointer
+         */
+        const sockaddr* get_sockaddr (socklen_t &len_ref) const;
+
+        /**
+         * Set a sockaddr for this address
+         *
+         * @param addr the address to copy, of len bytes
+         * @param len the size of the sockaddr
+         */
+        void set_sockaddr (const sockaddr *addr, socklen_t len);
+
+        /**
+         * Get the human-readable hostname
+         */
+        std::string get_hostname (void) const { return hostname; }
+
+        /**
+         * Get the human-readable service name
+         */
+        std::string get_service (void) const { return service; }
+
+        /**
+         * Equal-to comparison operator. This requires that the machine-readable address be available.
+         */
+        bool operator== (const NetworkAddress &other) const {
+            return (address_length == other.address_length) && memcmp(&address, &other.address, address_length) == 0;
+        }
+
+        /**
+         * Not-qqual-to comparison operator. This requires that the machine-readable address be available.
+         */
+        bool operator!= (const NetworkAddress &other) const {
+            return (address_length != other.address_length) || memcmp(&address, &other.address, address_length) != 0;
+        }
+
+        /**
+         * Less-than comparison operator. Smaller addresses are always lesser.
+         */
+        bool operator< (const NetworkAddress &other) const {
+            return (address_length < other.address_length) || memcmp(&address, &other.address, other.address_length) < 0;
+        }
+
+        /**
+         * Greater-than comparison operator. Bigger addresses are always greater.
+         */
+        bool operator> (const NetworkAddress &other) const {
+            return (address_length > other.address_length) || memcmp(&address, &other.address, address_length) > 0;
+        }
+};
 
 /**
  * Formatted as  [<addr>:<port>]
  */
 std::ostream& operator<< (std::ostream &s, const NetworkAddress &addr);
 
+/**
+ *
+ */
+class NetworkAddressError : public Error {
+    protected:
+        static std::string build_str (const NetworkAddress &addr, const char *op, const char *msg);
+
+    public:
+        NetworkAddressError (const NetworkAddress &addr, const char *op, const char *msg);
+};
+
 #endif /* NETWORK_ADDRESS_HH */