#include <string>
#include <type_traits>
-#include <folly/Conv.h>
+#include <folly/Format.h>
#include <folly/detail/IPAddress.h>
// BSDish platforms don't provide standard access to s6_addr16
std::size_t asize = a.size();
std::array<uint8_t, N> ba{{0}};
for (std::size_t i = 0; i < asize; i++) {
- ba[i] = a[i] & b[i];
+ ba[i] = uint8_t(a[i] & b[i]);
}
return ba;
}
0xff // /8
}};
if (oneMask > kBitCount || twoMask > kBitCount) {
- throw std::invalid_argument(folly::to<std::string>(
- "Invalid mask "
- "length: ",
- oneMask > twoMask ? oneMask : twoMask,
- ". Mask length must be <= ",
+ throw std::invalid_argument(sformat(
+ "Invalid mask length: {}. Mask length must be <= {}",
+ std::max(oneMask, twoMask),
kBitCount));
}
ba[byteIndex] = one[byteIndex];
++byteIndex;
}
- auto bitIndex = std::min(mask, (uint8_t)(byteIndex * 8));
+ auto bitIndex = std::min(mask, uint8_t(byteIndex * 8));
+ uint8_t bI = uint8_t(bitIndex / 8);
+ uint8_t bM = uint8_t(bitIndex % 8);
// Compute the bit up to which the two byte arrays match in the
// unmatched byte.
// Here the check is bitIndex < mask since the 0th mask entry in
// kMasks array holds the mask for masking the MSb in this byte.
// We could instead make it hold so that no 0th entry masks no
// bits but thats a useless iteration.
- while (bitIndex < mask && ((one[bitIndex / 8] & kMasks[bitIndex % 8]) ==
- (two[bitIndex / 8] & kMasks[bitIndex % 8]))) {
- ba[bitIndex / 8] = one[bitIndex / 8] & kMasks[bitIndex % 8];
+ while (bitIndex < mask &&
+ ((one[bI] & kMasks[bM]) == (two[bI] & kMasks[bM]))) {
+ ba[bI] = uint8_t(one[bI] & kMasks[bM]);
++bitIndex;
+ bI = uint8_t(bitIndex / 8);
+ bM = uint8_t(bitIndex % 8);
}
return {ba, bitIndex};
}
template <
class IntegralType,
IntegralType DigitCount,
- IntegralType Base = 10,
+ IntegralType Base = IntegralType(10),
bool PrintAllDigits = false,
class = typename std::enable_if<
std::is_integral<IntegralType>::value &&
}
IntegralType powerToPrint = 1;
- for (int i = 1; i < DigitCount; ++i) {
+ for (IntegralType i = 1; i < DigitCount; ++i) {
powerToPrint *= Base;
}
bool found = PrintAllDigits;
while (powerToPrint) {
if (found || powerToPrint <= val) {
- IntegralType value = val / powerToPrint;
+ IntegralType value = IntegralType(val / powerToPrint);
if (Base == 10 || value < 10) {
value += '0';
} else {
*buffer = buf;
}
-inline std::string fastIpv4ToString(const in_addr& inAddr) {
+inline size_t fastIpV4ToBufferUnsafe(const in_addr& inAddr, char* str) {
const uint8_t* octets = reinterpret_cast<const uint8_t*>(&inAddr.s_addr);
- char str[sizeof("255.255.255.255")];
char* buf = str;
writeIntegerString<uint8_t, 3>(octets[0], &buf);
*(buf++) = '.';
writeIntegerString<uint8_t, 3>(octets[3], &buf);
- return std::string(str, size_t(buf - str));
+ return buf - str;
}
-inline std::string fastIpv6ToString(const in6_addr& in6Addr) {
+inline std::string fastIpv4ToString(const in_addr& inAddr) {
+ char str[sizeof("255.255.255.255")];
+ return std::string(str, fastIpV4ToBufferUnsafe(inAddr, str));
+}
+
+inline void fastIpv4AppendToString(const in_addr& inAddr, std::string& out) {
+ char str[sizeof("255.255.255.255")];
+ out.append(str, fastIpV4ToBufferUnsafe(inAddr, str));
+}
+
+inline size_t fastIpv6ToBufferUnsafe(const in6_addr& in6Addr, char* str) {
#ifdef _MSC_VER
const uint16_t* bytes = reinterpret_cast<const uint16_t*>(&in6Addr.u.Word);
#else
const uint16_t* bytes = reinterpret_cast<const uint16_t*>(&in6Addr.s6_addr16);
#endif
- char str[sizeof("2001:0db8:0000:0000:0000:ff00:0042:8329")];
char* buf = str;
for (int i = 0; i < 8; ++i) {
}
}
- return std::string(str, size_t(buf - str));
+ return buf - str;
}
+
+inline std::string fastIpv6ToString(const in6_addr& in6Addr) {
+ char str[sizeof("2001:0db8:0000:0000:0000:ff00:0042:8329")];
+ return std::string(str, fastIpv6ToBufferUnsafe(in6Addr, str));
}
+
+inline void fastIpv6AppendToString(const in6_addr& in6Addr, std::string& out) {
+ char str[sizeof("2001:0db8:0000:0000:0000:ff00:0042:8329")];
+ out.append(str, fastIpv6ToBufferUnsafe(in6Addr, str));
}
+} // namespace detail
+} // namespace folly