util: use C++11 features in ethernet::Address class.

Change-Id: I2740575c26d485ac13b1688cb8a74426145d8bae
diff --git a/src/util/ethernet.cpp b/src/util/ethernet.cpp
index f68a27a..ae52005 100644
--- a/src/util/ethernet.cpp
+++ b/src/util/ethernet.cpp
@@ -27,40 +27,26 @@
 
 #include "ethernet.hpp"
 
-#include <stdio.h>
+#include <cstdio>
 #include <ostream>
 
 namespace ndn {
 namespace util {
 namespace ethernet {
 
-Address
-getBroadcastAddress()
-{
-  static Address bcast(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
-  return bcast;
-}
-
-Address
-getDefaultMulticastAddress()
-{
-  static Address mcast(0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA);
-  return mcast;
-}
-
 Address::Address()
 {
-  assign(0);
+  fill(0);
 }
 
 Address::Address(uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6)
 {
-  elems[0] = a1;
-  elems[1] = a2;
-  elems[2] = a3;
-  elems[3] = a4;
-  elems[4] = a5;
-  elems[5] = a6;
+  data()[0] = a1;
+  data()[1] = a2;
+  data()[2] = a3;
+  data()[3] = a4;
+  data()[4] = a5;
+  data()[5] = a6;
 }
 
 Address::Address(const uint8_t octets[])
@@ -68,59 +54,53 @@
   std::copy(octets, octets + size(), begin());
 }
 
-Address::Address(const Address& address)
-{
-  std::copy(address.begin(), address.end(), begin());
-}
-
 bool
 Address::isBroadcast() const
 {
-  return elems[0] == 0xFF && elems[1] == 0xFF && elems[2] == 0xFF &&
-         elems[3] == 0xFF && elems[4] == 0xFF && elems[5] == 0xFF;
+  return *this == getBroadcastAddress();
 }
 
 bool
 Address::isMulticast() const
 {
-  return (elems[0] & 1) != 0;
+  return (at(0) & 1) != 0;
 }
 
 bool
 Address::isNull() const
 {
-  return elems[0] == 0x0 && elems[1] == 0x0 && elems[2] == 0x0 &&
-         elems[3] == 0x0 && elems[4] == 0x0 && elems[5] == 0x0;
+  return *this == Address();
 }
 
 std::string
 Address::toString(char sep) const
 {
   char s[18]; // 12 digits + 5 separators + null terminator
-  ::snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
-             elems[0], sep, elems[1], sep, elems[2], sep,
-             elems[3], sep, elems[4], sep, elems[5]);
+
+  // apparently gcc-4.6 does not support the 'hh' type modifier
+  std::snprintf(s, sizeof(s), "%02x%c%02x%c%02x%c%02x%c%02x%c%02x",
+                at(0), sep, at(1), sep, at(2), sep, at(3), sep, at(4), sep, at(5));
+
   return std::string(s);
 }
 
 Address
 Address::fromString(const std::string& str)
 {
-  unsigned short temp[ADDR_LEN];
+  Address a;
+  unsigned short temp[a.size()];
   char sep[5][2]; // 5 * (1 separator char + 1 null terminator)
   int n = 0; // num of chars read from the input string
 
-  // ISO C++98 does not support the 'hh' type modifier
-  /// \todo use SCNx8 (cinttypes) when we enable C++11
-  int ret = ::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
-                     &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
-                     &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
+  // apparently gcc-4.6 does not support the 'hh' type modifier
+  int ret = std::sscanf(str.c_str(), "%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%1[:-]%2hx%n",
+                        &temp[0], &sep[0][0], &temp[1], &sep[1][0], &temp[2], &sep[2][0],
+                        &temp[3], &sep[3][0], &temp[4], &sep[4][0], &temp[5], &n);
 
   if (ret < 11 || static_cast<size_t>(n) != str.length())
     return Address();
 
-  Address a;
-  for (size_t i = 0; i < ADDR_LEN; ++i)
+  for (size_t i = 0; i < a.size(); ++i)
     {
       // check that all separators are actually the same char (: or -)
       if (i < 5 && sep[i][0] != sep[0][0])
@@ -136,6 +116,18 @@
   return a;
 }
 
+Address
+getBroadcastAddress()
+{
+  return { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+}
+
+Address
+getDefaultMulticastAddress()
+{
+  return { 0x01, 0x00, 0x5E, 0x00, 0x17, 0xAA };
+}
+
 std::ostream&
 operator<<(std::ostream& o, const Address& a)
 {
diff --git a/src/util/ethernet.hpp b/src/util/ethernet.hpp
index 11788f0..ac7cb94 100644
--- a/src/util/ethernet.hpp
+++ b/src/util/ethernet.hpp
@@ -28,15 +28,15 @@
 #ifndef NDN_UTIL_ETHERNET_HPP
 #define NDN_UTIL_ETHERNET_HPP
 
-#include "../common.hpp"
-
-#include <boost/array.hpp>
+#include <array>
+#include <cstdint>
+#include <string>
 
 namespace ndn {
 namespace util {
 namespace ethernet {
 
-static const uint16_t ETHERTYPE_NDN = 0x8624;
+const uint16_t ETHERTYPE_NDN = 0x8624;
 
 const size_t ADDR_LEN     = 6;      ///< Octets in one Ethernet address
 const size_t TYPE_LEN     = 2;      ///< Octets in Ethertype field
@@ -49,7 +49,7 @@
 
 /** \brief represents an Ethernet hardware address
  */
-class Address : public boost::array<uint8_t, ADDR_LEN>
+class Address : public std::array<uint8_t, ADDR_LEN>
 {
 public:
   /// Constructs a null Ethernet address (00:00:00:00:00:00)
@@ -63,9 +63,6 @@
   explicit
   Address(const uint8_t octets[ADDR_LEN]);
 
-  /// Copy constructor
-  Address(const Address& address);
-
   /// True if this is a broadcast address (ff:ff:ff:ff:ff:ff)
   bool
   isBroadcast() const;
diff --git a/tests/unit-tests/util/ethernet.cpp b/tests/unit-tests/util/ethernet.cpp
index 6db6585..2077f5a 100644
--- a/tests/unit-tests/util/ethernet.cpp
+++ b/tests/unit-tests/util/ethernet.cpp
@@ -34,9 +34,24 @@
 
 BOOST_AUTO_TEST_SUITE(UtilTestEthernet)
 
-BOOST_AUTO_TEST_CASE(Checks)
+BOOST_AUTO_TEST_CASE(BasicChecks)
 {
-  BOOST_CHECK(ethernet::Address().isNull());
+  ethernet::Address a;
+  BOOST_CHECK(a.isNull());
+
+  a = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB};
+  ethernet::Address b(0x01, 0x23, 0x45, 0x67, 0x89, 0xAB);
+  const uint8_t bytes[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB};
+  ethernet::Address c(bytes);
+  ethernet::Address d(a);
+  ethernet::Address e;
+  e = a;
+
+  BOOST_CHECK_EQUAL(a, b);
+  BOOST_CHECK_EQUAL(a, c);
+  BOOST_CHECK_EQUAL(a, d);
+  BOOST_CHECK_EQUAL(a, e);
+
   BOOST_CHECK(ethernet::getBroadcastAddress().isBroadcast());
   BOOST_CHECK(ethernet::getDefaultMulticastAddress().isMulticast());
 }