/*
- * Copyright 2014 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.
* limitations under the License.
*/
-#include "MacAddress.h"
+#include <folly/MacAddress.h>
-#include "folly/Exception.h"
-#include "folly/IPAddressV6.h"
+#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;
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
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);
}
return os;
}
-} // folly
+} // namespace folly