27 #include <glog/logging.h> 48 index ==
'\\' ?
'\\' :
53 index < 32 || index > 126 ?
'O' :
63 index ==
'\'' ?
'\'' :
65 index ==
'\\' ?
'\\' :
74 index >=
'0' && index <=
'7' ?
'O' :
82 constexpr
unsigned char operator()(std::size_t index)
const {
85 index >=
'0' && index <=
'9' ? index -
'0' :
86 index >=
'a' && index <=
'f' ? index -
'a' + 10 :
87 index >=
'A' && index <=
'F' ? index -
'A' + 10 :
99 constexpr
unsigned char operator()(std::size_t index)
const {
102 index >=
'0' && index <=
'9' ? 0 :
103 index >=
'A' && index <=
'Z' ? 0 :
104 index >=
'a' && index <=
'z' ? 0 :
128 return c ==
'\n' || c ==
'\t' || c ==
'\r';
155 while (!sp.
empty() && sp.
back() ==
' ') {
169 int stringAppendfImplHelper(
175 va_copy(args_copy, args);
176 int bytes_used = vsnprintf(buf, bufsize, format, args_copy);
192 std::array<char, 128> inline_buffer;
194 int bytes_used = stringAppendfImplHelper(
195 inline_buffer.data(), inline_buffer.size(),
format, args);
196 if (bytes_used < 0) {
197 throw std::runtime_error(to<std::string>(
198 "Invalid format string; snprintf returned negative " 199 "with format string: ",
203 if (static_cast<size_t>(bytes_used) < inline_buffer.size()) {
204 output.append(inline_buffer.data(), size_t(bytes_used));
209 std::unique_ptr<char[]> heap_buffer(
new char[
size_t(bytes_used + 1)]);
210 int final_bytes_used = stringAppendfImplHelper(
211 heap_buffer.get(), size_t(bytes_used + 1),
format, args);
215 CHECK(bytes_used >= final_bytes_used);
218 output.append(heap_buffer.get(), size_t(final_bytes_used));
225 va_start(ap, format);
234 stringAppendfImpl(ret, format, ap);
242 va_start(ap, format);
251 stringAppendfImpl(*output, format, ap);
257 va_start(ap, format);
266 stringAppendfImpl(*output, format, ap);
271 struct PrettySuffix {
276 const PrettySuffix kPrettyTimeSuffixes[] = {
286 const PrettySuffix kPrettyTimeHmsSuffixes[] = {
298 const PrettySuffix kPrettyBytesMetricSuffixes[] = {
309 const PrettySuffix kPrettyBytesBinarySuffixes[] = {
320 const PrettySuffix kPrettyBytesBinaryIECSuffixes[] = {
331 const PrettySuffix kPrettyUnitsMetricSuffixes[] = {
342 const PrettySuffix kPrettyUnitsBinarySuffixes[] = {
353 const PrettySuffix kPrettyUnitsBinaryIECSuffixes[] = {
364 const PrettySuffix kPrettySISuffixes[] = {
365 {
"Y", 1e24L}, {
"Z", 1e21L}, {
"E", 1e18L}, {
"P", 1e15L}, {
"T", 1e12L},
366 {
"G", 1e9L}, {
"M", 1e6L}, {
"k", 1e3L}, {
"h", 1e2L}, {
"da", 1e1L},
367 {
"d", 1e-1L}, {
"c", 1e-2L}, {
"m", 1e-3L}, {
"u", 1e-6L}, {
"n", 1e-9L},
368 {
"p", 1e-12L}, {
"f", 1e-15L}, {
"a", 1e-18L}, {
"z", 1e-21L}, {
"y", 1e-24L},
369 {
" ", 0}, {
nullptr, 0},
374 kPrettyTimeHmsSuffixes,
375 kPrettyBytesMetricSuffixes,
376 kPrettyBytesBinarySuffixes,
377 kPrettyBytesBinaryIECSuffixes,
378 kPrettyUnitsMetricSuffixes,
379 kPrettyUnitsBinarySuffixes,
380 kPrettyUnitsBinaryIECSuffixes,
392 const PrettySuffix* suffixes = kPrettySuffixes[
type];
395 double abs_val = fabs(val);
396 for (
int i = 0; suffixes[
i].suffix; ++
i) {
397 if (abs_val >= suffixes[
i].val) {
402 (suffixes[
i].val ? (val / suffixes[
i].val) : val),
403 (addSpace ?
" " :
""),
410 snprintf(buf,
sizeof buf,
"%.4g", val);
419 double value = folly::to<double>(prettyString);
420 while (prettyString->
size() > 0 && std::isspace(prettyString->
front())) {
423 const PrettySuffix* suffixes = kPrettySuffixes[
type];
424 int longestPrefixLen = -1;
425 int bestPrefixId = -1;
426 for (
int j = 0; suffixes[j].suffix; ++j) {
427 if (suffixes[j].
suffix[0] ==
' ') {
428 if (longestPrefixLen == -1) {
429 longestPrefixLen = 0;
432 }
else if (prettyString->
startsWith(suffixes[j].suffix)) {
433 int suffixLen = int(strlen(suffixes[j].
suffix));
436 if (suffixLen > longestPrefixLen) {
437 longestPrefixLen = suffixLen;
442 if (bestPrefixId == -1) {
443 throw std::invalid_argument(folly::to<std::string>(
444 "Unable to parse suffix \"", *prettyString,
"\""));
446 prettyString->
advance(
size_t(longestPrefixLen));
447 return suffixes[bestPrefixId].val ? value * suffixes[bestPrefixId].val
458 std::ostringstream os;
459 hexDump(ptr, size, std::ostream_iterator<StringPiece>(os,
"\n"));
464 int savedErrno = errno;
476 #if defined(_WIN32) && (defined(__MINGW32__) || defined(_MSC_VER)) 480 int r = strerror_s(buf,
sizeof(buf), err);
482 result = to<fbstring>(
483 "Unknown error ", err,
" (strerror_r failed with error ", errno,
")");
487 #elif FOLLY_HAVE_XSI_STRERROR_R || defined(__APPLE__) 490 int r = strerror_r(err, buf,
sizeof(buf));
494 result = to<fbstring>(
495 "Unknown error ", err,
" (strerror_r failed with error ", errno,
")");
501 result.
assign(strerror_r(err, buf,
sizeof(buf)));
509 void toLowerAscii8(
char&
c) {
590 rotated +=
uint64_t(0x2525252525252525L);
591 rotated &=
uint64_t(0x7f7f7f7f7f7f7f7fL);
592 rotated +=
uint64_t(0x1a1a1a1a1a1a1a1aL);
595 rotated &=
uint64_t(0x2020202020202020L);
602 static const size_t kAlignMask64 = 7;
603 static const size_t kAlignMask32 = 3;
607 size_t n = (size_t)str;
614 toLowerAscii8(str[offset]);
616 }
while (offset < n);
619 n = (size_t)(str + offset);
621 if ((n != 0) && (offset + 4 <= length)) {
625 toLowerAscii32(*(
uint32_t*)(str + offset));
630 while (offset + 8 <= length) {
631 toLowerAscii64(*(
uint64_t*)(str + offset));
636 while (offset + 4 <= length) {
637 toLowerAscii32(*(
uint32_t*)(str + offset));
642 while (offset < length) {
643 toLowerAscii8(str[offset]);
652 static char hexValues[] =
"0123456789abcdef";
665 size_t n =
std::min(size - offset,
size_t(16));
666 line.push_back(hexValues[(offset >> 28) & 0xf]);
667 line.push_back(hexValues[(offset >> 24) & 0xf]);
668 line.push_back(hexValues[(offset >> 20) & 0xf]);
669 line.push_back(hexValues[(offset >> 16) & 0xf]);
670 line.push_back(hexValues[(offset >> 12) & 0xf]);
671 line.push_back(hexValues[(offset >> 8) & 0xf]);
672 line.push_back(hexValues[(offset >> 4) & 0xf]);
673 line.push_back(hexValues[offset & 0xf]);
676 for (
size_t i = 0;
i < n;
i++) {
682 line.push_back(hexValues[(p[
i] >> 4) & 0xf]);
683 line.push_back(hexValues[p[
i] & 0xf]);
688 line.append(3 * (16 - n) + (n <= 8),
' ');
691 for (
size_t i = 0;
i < n;
i++) {
692 char c = (p[
i] >= 32 && p[
i] <= 126 ?
static_cast<char>(p[
i]) :
'.');
695 line.append(16 - n,
' ');
697 DCHECK_EQ(line.size(), 78u);
705 std::vector<StringPiece> pieces;
706 split(
"\n", s, pieces);
707 auto piecer =
range(pieces);
709 auto piece = (piecer.end() - 1);
710 auto needle = std::find_if(piece->begin(), piece->end(), [](
char c) {
711 return c !=
' ' &&
c !=
'\t';
713 if (
needle == piece->end()) {
714 (piecer.end() - 1)->clear();
716 piece = piecer.begin();
717 needle = std::find_if(piece->begin(), piece->end(), [](
char c) {
718 return c !=
' ' &&
c !=
'\t';
720 if (
needle == piece->end()) {
721 piecer.erase(piecer.begin(), piecer.begin() + 1);
725 auto indent = sentinel;
726 size_t max_length = 0;
727 for (piece = piecer.begin(); piece != piecer.end(); piece++) {
728 needle = std::find_if(piece->begin(), piece->end(), [](
char c) {
729 return c !=
' ' &&
c !=
'\t';
731 if (
needle != piece->end()) {
732 indent = std::min<size_t>(indent, size_t(
needle - piece->begin()));
734 max_length = std::max<size_t>(piece->size(), max_length);
737 indent = indent == sentinel ? max_length : indent;
738 for (piece = piecer.begin(); piece != piecer.end(); piece++) {
739 if (piece->size() < indent) {
742 piece->erase(piece->begin(), piece->begin() + indent);
745 return join(
"\n", piecer);
750 #ifdef FOLLY_DEFINED_DMGL 751 #undef FOLLY_DEFINED_DMGL 758 #undef DMGL_RET_POSTFIX
StringPiece ltrimWhitespace(StringPiece sp)
const std::array< unsigned char, 256 > uriEscapeTable
const std::array< char, 256 > cEscapeTable
void advance(size_type n)
std::string stringVPrintf(const char *format, va_list ap)
constexpr size_type size() const
void enforceWhitespace(StringPiece sp)
std::string stringPrintf(const char *format,...)
std::string & stringVAppendf(std::string *output, const char *format, va_list ap)
—— Concurrent Priority Queue Implementation ——
void split(const Delim &delimiter, const String &input, std::vector< OutputType > &out, bool ignoreEmpty)
std::string prettyPrint(double val, PrettyType type, bool addSpace)
std::string stripLeftMargin(std::string s)
const std::array< unsigned char, 256 > hexTable
StrictConjunction< std::is_constructible< To, From >, std::is_assignable< To &, From >> IsConvertible
constexpr auto size(C const &c) -> decltype(c.size())
constexpr bool empty() const
constexpr unsigned char operator()(std::size_t index) const
constexpr char operator()(std::size_t index) const
size_t hexDumpLine(const void *ptr, size_t offset, size_t size, std::string &line)
constexpr unsigned char operator()(std::size_t index) const
GuardImpl guard(ErrorHandler &&handler)
StringPiece rtrimWhitespace(StringPiece sp)
#define FOLLY_STORAGE_CONSTEXPR
constexpr Range< Iter > range(Iter first, Iter last)
void hexDump(const void *ptr, size_t size, OutIt out)
const std::array< char, 256 > cUnescapeTable
static const char *const value
std::string & stringAppendf(std::string *output, const char *format,...)
fbstring errnoStr(int err)
double prettyToDouble(folly::StringPiece *const prettyString, const PrettyType type)
constexpr char operator()(std::size_t index) const
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
bool startsWith(const const_range_type &other) const
void toLowerAscii(char *str, size_t length)
basic_fbstring & assign(const basic_fbstring &str)
constexpr auto make_array_with(MakeItem const &make)
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
void join(const Delim &delimiter, Iterator begin, Iterator end, String &output)
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
static bool is_oddspace(char c)