+/* $Id$
+
+This file is part of libmspnet
+Copyright © 2011 Mikkosoft Productions, Mikko Rasa
+Distributed under the LGPL
+*/
+
+#include <msp/core/except.h>
+#include <msp/strings/formatter.h>
+#include "inet6.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Net {
+
+Inet6Addr::Inet6Addr():
+ addr(in6addr_any),
+ port(0)
+{ }
+
+Inet6Addr::Inet6Addr(const sockaddr_in6 &sai6):
+ addr(sai6.sin6_addr),
+ port(sai6.sin6_port)
+{ }
+
+Inet6Addr::Inet6Addr(unsigned char a[16], in_port_t p):
+ port(p)
+{
+ std::copy(a, a+16, addr.s6_addr);
+}
+
+string Inet6Addr::str() const
+{
+ string result = "[";
+ for(unsigned i=0; i<16; i+=2)
+ {
+ unsigned short part = (addr.s6_addr[i]<<8) | addr.s6_addr[i+1];
+ if(i>0)
+ result += ':';
+ result += format("%x", part);
+ }
+ result += ']';
+ if(port)
+ result += format(":%d", ntohs(port));
+
+ return result;
+}
+
+unsigned Inet6Addr::fill_sockaddr(sockaddr &) const
+{
+ throw Exception("Inet6Addr doesn't fit in struct sockaddr");
+}
+
+unsigned Inet6Addr::fill_sockaddr(sockaddr_storage &sa) const
+{
+ sockaddr_in6 &sai6 = reinterpret_cast<sockaddr_in6 &>(sa);
+ sai6.sin6_family = AF_INET6;
+ sai6.sin6_port = port;
+ sai6.sin6_addr = addr;
+ sai6.sin6_flowinfo = 0;
+ sai6.sin6_scope_id = 0;
+
+ return sizeof(sockaddr_in6);
+}
+
+} // namespace Net
+} // namespace Msp