cmake: support using a separate build directory
[folly.git] / folly / MacAddress.cpp
index 1ce5d1ec3615ace3fd22a7798bcafc31545e864e..c806d9b7feb21ca820e892886ce12caaa7be3d56 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,7 +19,9 @@
 #include <ostream>
 
 #include <folly/Exception.h>
+#include <folly/Format.h>
 #include <folly/IPAddressV6.h>
+#include <folly/String.h>
 
 using std::invalid_argument;
 using std::string;
@@ -71,70 +73,62 @@ string MacAddress::toString() const {
 
 void MacAddress::parse(StringPiece str) {
   // Helper function to convert a single hex char into an integer
-  auto unhex = [](char c) -> int {
-    return c >= '0' && c <= '9' ? c - '0' :
-           c >= 'A' && c <= 'F' ? c - 'A' + 10 :
-           c >= 'a' && c <= 'f' ? c - 'a' + 10 :
-           -1;
-  };
-  auto isSeparatorChar = [](char c) {
-    return c == ':' || c == '-';
-  };
+  auto isSeparatorChar = [](char c) { return c == ':' || c == '-'; };
 
   uint8_t parsed[SIZE];
   auto p = str.begin();
   for (unsigned int byteIndex = 0; byteIndex < SIZE; ++byteIndex) {
     if (p == str.end()) {
-      throw invalid_argument(to<string>("invalid MAC address \"", str,
-                                        "\": not enough digits"));
+      throw invalid_argument(
+          sformat("invalid MAC address '{}': not enough digits", str));
     }
 
     // Skip over ':' or '-' separators between bytes
     if (byteIndex != 0 && isSeparatorChar(*p)) {
       ++p;
       if (p == str.end()) {
-        throw invalid_argument(to<string>("invalid MAC address \"", str,
-                                          "\": not enough digits"));
+        throw invalid_argument(
+            sformat("invalid MAC address '{}': not enough digits", str));
       }
     }
 
     // Parse the upper nibble
-    int upper = unhex(*p);
-    if (upper 0) {
-      throw invalid_argument(to<string>("invalid MAC address \"", str,
-                                        "\": contains non-hex digit"));
+    uint8_t upper = detail::hexTable[static_cast<uint8_t>(*p)];
+    if (upper & 0x10) {
+      throw invalid_argument(
+          sformat("invalid MAC address '{}': contains non-hex digit", str));
     }
     ++p;
 
     // Parse the lower nibble
-    int lower;
+    uint8_t lower;
     if (p == str.end()) {
       lower = upper;
       upper = 0;
     } else {
-      lower = unhex(*p);
-      if (lower 0) {
+      lower = detail::hexTable[static_cast<uint8_t>(*p)];
+      if (lower & 0x10) {
         // Also accept ':', '-', or '\0', to handle the case where one
         // of the bytes was represented by just a single digit.
         if (isSeparatorChar(*p)) {
           lower = upper;
           upper = 0;
         } else {
-          throw invalid_argument(to<string>("invalid MAC address \"", str,
-                                            "\": contains non-hex digit"));
+          throw invalid_argument(
+              sformat("invalid MAC address '{}': contains non-hex digit", str));
         }
       }
       ++p;
     }
 
     // Update parsed with the newly parsed byte
-    parsed[byteIndex] = ((upper << 4) | lower);
+    parsed[byteIndex] = (upper << 4) | lower;
   }
 
   if (p != str.end()) {
     // String is too long to be a MAC address
-    throw invalid_argument(to<string>("invalid MAC address \"", str,
-                                      "\": found trailing characters"));
+    throw invalid_argument(
+        sformat("invalid MAC address '{}': found trailing characters", str));
   }
 
   // Only update now that we have successfully parsed the entire
@@ -144,8 +138,8 @@ void MacAddress::parse(StringPiece str) {
 
 void MacAddress::setFromBinary(ByteRange value) {
   if (value.size() != SIZE) {
-    throw invalid_argument(to<string>("MAC address must be 6 bytes "
-                                      "long, got ", value.size()));
+    throw invalid_argument(
+        sformat("MAC address must be 6 bytes long, got ", value.size()));
   }
   memcpy(bytes_ + 2, value.begin(), SIZE);
 }
@@ -155,4 +149,4 @@ std::ostream& operator<<(std::ostream& os, MacAddress address) {
   return os;
 }
 
-} // folly
+} // namespace folly