Compute masks in IPAddressV4
authorYedidya Feldblum <yfeldblum@fb.com>
Sat, 29 Jul 2017 18:51:38 +0000 (11:51 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 29 Jul 2017 19:08:28 +0000 (12:08 -0700)
Summary: [Folly] Compute masks in `IPAddressV4`. Just like in `IPAddressV6`.

Reviewed By: WillerZ

Differential Revision: D5524197

fbshipit-source-id: ebeeab28304bff4f6150cf76216d170908e62aa4

folly/IPAddressV4.cpp
folly/IPAddressV4.h
folly/test/IPAddressTest.cpp

index cd81d6d979f656fea67459e48e17c5ed83cc7cae..bcd582df89280ea5dd9d09298a36359561e8a60a 100644 (file)
@@ -273,8 +273,10 @@ const ByteArray4 IPAddressV4::fetchMask(size_t numBits) {
     throw IPAddressFormatException(
         to<std::string>("IPv4 addresses are 32 bits"));
   }
-  // masks_ is backed by an array so is zero indexed
-  return masks_[numBits];
+  auto const val = Endian::big(uint32_t(~uint64_t(0) << (32 - numBits)));
+  ByteArray4 arr;
+  std::memcpy(arr.data(), &val, sizeof(val));
+  return arr;
 }
 // public static
 CIDRNetworkV4 IPAddressV4::longestCommonPrefix(
@@ -285,41 +287,4 @@ CIDRNetworkV4 IPAddressV4::longestCommonPrefix(
   return {IPAddressV4(prefix.first), prefix.second};
 }
 
-// static private
-const std::array<ByteArray4, 33> IPAddressV4::masks_ = {{
-  {{0x00, 0x00, 0x00, 0x00}},
-  {{0x80, 0x00, 0x00, 0x00}},
-  {{0xc0, 0x00, 0x00, 0x00}},
-  {{0xe0, 0x00, 0x00, 0x00}},
-  {{0xf0, 0x00, 0x00, 0x00}},
-  {{0xf8, 0x00, 0x00, 0x00}},
-  {{0xfc, 0x00, 0x00, 0x00}},
-  {{0xfe, 0x00, 0x00, 0x00}},
-  {{0xff, 0x00, 0x00, 0x00}},
-  {{0xff, 0x80, 0x00, 0x00}},
-  {{0xff, 0xc0, 0x00, 0x00}},
-  {{0xff, 0xe0, 0x00, 0x00}},
-  {{0xff, 0xf0, 0x00, 0x00}},
-  {{0xff, 0xf8, 0x00, 0x00}},
-  {{0xff, 0xfc, 0x00, 0x00}},
-  {{0xff, 0xfe, 0x00, 0x00}},
-  {{0xff, 0xff, 0x00, 0x00}},
-  {{0xff, 0xff, 0x80, 0x00}},
-  {{0xff, 0xff, 0xc0, 0x00}},
-  {{0xff, 0xff, 0xe0, 0x00}},
-  {{0xff, 0xff, 0xf0, 0x00}},
-  {{0xff, 0xff, 0xf8, 0x00}},
-  {{0xff, 0xff, 0xfc, 0x00}},
-  {{0xff, 0xff, 0xfe, 0x00}},
-  {{0xff, 0xff, 0xff, 0x00}},
-  {{0xff, 0xff, 0xff, 0x80}},
-  {{0xff, 0xff, 0xff, 0xc0}},
-  {{0xff, 0xff, 0xff, 0xe0}},
-  {{0xff, 0xff, 0xff, 0xf0}},
-  {{0xff, 0xff, 0xff, 0xf8}},
-  {{0xff, 0xff, 0xff, 0xfc}},
-  {{0xff, 0xff, 0xff, 0xfe}},
-  {{0xff, 0xff, 0xff, 0xff}}
-}};
-
 } // folly
index 2de04f1c4ab568ef255b9507714770e59df7c506..1e2c65e7f91d60a895dcd3915bf996d338635ab7 100644 (file)
@@ -269,8 +269,6 @@ class IPAddressV4 {
     explicit AddressStorage(const in_addr addr): inAddr_(addr) {}
   } addr_;
 
-  static const std::array<ByteArray4, 33> masks_;
-
   /**
    * Set the current IPAddressV4 object to have the address specified by bytes.
    * @throws IPAddressFormatException if bytes.size() is not 4.
index 2f93e466313874607d9b21eb39771d83806f0a2f..0d6bca5ee8fbc25e5f1dc7f12fe7e3cf469e1639 100644 (file)
@@ -1272,6 +1272,28 @@ INSTANTIATE_TEST_CASE_P(IPAddress,
                         IPAddressBitAccessorTest,
                         ::testing::ValuesIn(validAddressProvider));
 
+TEST(IPAddressV4, fetchMask) {
+  struct X : private IPAddressV4 {
+    using IPAddressV4::fetchMask;
+  };
+
+  EXPECT_THAT(
+      X::fetchMask(0),
+      ::testing::ElementsAreArray(ByteArray4{{0x00, 0x00, 0x00, 0x00}}));
+
+  EXPECT_THAT(
+      X::fetchMask(1),
+      ::testing::ElementsAreArray(ByteArray4{{0x80, 0x00, 0x00, 0x00}}));
+
+  EXPECT_THAT(
+      X::fetchMask(31),
+      ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xfe}}));
+
+  EXPECT_THAT(
+      X::fetchMask(32),
+      ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xff}}));
+}
+
 TEST(IPAddressV6, fetchMask) {
   using ByteArray8 = std::array<uint8_t, 8>;