MCPcopy Create free account
hub / github.com/apache/brpc / StringAppendVT

Function StringAppendVT

src/butil/strings/stringprintf.cc:48–113  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

46// the va_list, the caller is expected to do that.
47template <class StringType>
48static void StringAppendVT(StringType* dst,
49 const typename StringType::value_type* format,
50 va_list ap) {
51 // First try with a small fixed size buffer.
52 // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
53 // and StringUtilTest.StringPrintfBounds.
54 typename StringType::value_type stack_buf[1024];
55
56 va_list ap_copy;
57 GG_VA_COPY(ap_copy, ap);
58
59#if !defined(OS_WIN)
60 ScopedClearErrno clear_errno;
61#endif
62 int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, ap_copy);
63 va_end(ap_copy);
64
65 if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) {
66 // It fit.
67 dst->append(stack_buf, result);
68 return;
69 }
70
71 // Repeatedly increase buffer size until it fits.
72 int mem_length = arraysize(stack_buf);
73 while (true) {
74 if (result < 0) {
75#if defined(OS_WIN)
76 // On Windows, vsnprintfT always returns the number of characters in a
77 // fully-formatted string, so if we reach this point, something else is
78 // wrong and no amount of buffer-doubling is going to fix it.
79 return;
80#else
81 if (errno != 0 && errno != EOVERFLOW && errno != E2BIG)
82 return;
83 // Try doubling the buffer size.
84 mem_length *= 2;
85#endif
86 } else {
87 // We need exactly "result + 1" characters.
88 mem_length = result + 1;
89 }
90
91 if (mem_length > 32 * 1024 * 1024) {
92 // That should be plenty, don't try anything larger. This protects
93 // against huge allocations when using vsnprintfT implementations that
94 // return -1 for reasons other than overflow without setting errno.
95 DLOG(WARNING) << "Unable to printf the requested string due to size.";
96 return;
97 }
98
99 std::vector<typename StringType::value_type> mem_buf(mem_length);
100
101 // NOTE: You can only use a va_list once. Since we're in a while loop, we
102 // need to make a new copy each time so we don't use up the original.
103 GG_VA_COPY(ap_copy, ap);
104 result = vsnprintfT(&mem_buf[0], mem_length, format, ap_copy);
105 va_end(ap_copy);

Callers 1

StringAppendVFunction · 0.85

Calls 2

vsnprintfTFunction · 0.85
appendMethod · 0.45

Tested by

no test coverage detected