69void PrintByteSegmentInObjectTo(
const unsigned char* obj_bytes,
size_t start,
70 size_t count, ostream* os) {
72 for (
size_t i = 0;
i !=
count;
i++) {
73 const size_t j = start +
i;
88void PrintBytesInObjectToImpl(
const unsigned char* obj_bytes,
size_t count,
91 *os <<
count <<
"-byte object <";
93 const size_t kThreshold = 132;
94 const size_t kChunkSize = 64;
98 if (
count < kThreshold) {
99 PrintByteSegmentInObjectTo(obj_bytes, 0,
count, os);
101 PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
104 const size_t resume_pos = (
count - kChunkSize + 1)/2*2;
105 PrintByteSegmentInObjectTo(obj_bytes, resume_pos,
count - resume_pos, os);
114template <
typename CharType>
115char32_t ToChar32(CharType in) {
116 return static_cast<char32_t>(
131 PrintBytesInObjectToImpl(obj_bytes,
count, os);
153template <
typename Char>
155 const char32_t u_c = ToChar32(c);
189 *os << static_cast<char>(c);
192 ostream::fmtflags flags = os->flags();
193 *os <<
"\\x" << std::hex << std::uppercase << static_cast<int>(u_c);
203static CharFormat PrintAsStringLiteralTo(
char32_t c, ostream* os) {
212 return PrintAsCharLiteralTo(c, os);
216static const char* GetCharWidthPrefix(
char) {
220static const char* GetCharWidthPrefix(
signed char) {
224static const char* GetCharWidthPrefix(
unsigned char) {
229static const char* GetCharWidthPrefix(
char8_t) {
234static const char* GetCharWidthPrefix(
char16_t) {
238static const char* GetCharWidthPrefix(
char32_t) {
242static const char* GetCharWidthPrefix(
wchar_t) {
248static CharFormat PrintAsStringLiteralTo(
char c, ostream* os) {
249 return PrintAsStringLiteralTo(ToChar32(c), os);
253static CharFormat PrintAsStringLiteralTo(
char8_t c, ostream* os) {
254 return PrintAsStringLiteralTo(ToChar32(c), os);
258static CharFormat PrintAsStringLiteralTo(
char16_t c, ostream* os) {
259 return PrintAsStringLiteralTo(ToChar32(c), os);
262static CharFormat PrintAsStringLiteralTo(
wchar_t c, ostream* os) {
263 return PrintAsStringLiteralTo(ToChar32(c), os);
269template <
typename Char>
272 *os << GetCharWidthPrefix(c) <<
"'";
273 const CharFormat format = PrintAsCharLiteralTo(c, os);
281 *os <<
" (" <<
static_cast<int>(c);
286 if (format ==
kHexEscape || (1 <= c && c <= 9)) {
303 *os << std::hex <<
"U+" << std::uppercase << std::setfill(
'0') << std::setw(4)
304 <<
static_cast<uint32_t
>(c);
311template <
typename CharType>
317 const CharType* begin,
size_t len, ostream* os) {
318 const char*
const quote_prefix = GetCharWidthPrefix(*begin);
319 *os << quote_prefix <<
"\"";
320 bool is_previous_hex =
false;
322 for (
size_t index = 0; index < len; ++index) {
323 const CharType cur = begin[index];
324 if (is_previous_hex &&
IsXDigit(cur)) {
328 *os <<
"\" " << quote_prefix <<
"\"";
330 is_previous_hex = PrintAsStringLiteralTo(cur, os) ==
kHexEscape;
332 if (is_previous_hex) {
342template <
typename CharType>
347static void UniversalPrintCharArray(
348 const CharType* begin,
size_t len, ostream* os) {
356 if (len > 0 && begin[len - 1] ==
'\0') {
357 PrintCharsAsStringTo(begin, len - 1, os);
365 PrintCharsAsStringTo(begin, len, os);
366 *os <<
" (no terminating NUL)";
371 UniversalPrintCharArray(begin, len, os);
378 UniversalPrintCharArray(begin, len, os);
385 UniversalPrintCharArray(begin, len, os);
391 UniversalPrintCharArray(begin, len, os);
397 UniversalPrintCharArray(begin, len, os);
403template <
typename Char>
404void PrintCStringTo(
const Char* s, ostream* os) {
408 *os << ImplicitCast_<const void*>(s) <<
" pointing to ";
409 PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os);
415void PrintTo(
const char* s, ostream* os) { PrintCStringTo(s, os); }
418void PrintTo(
const char8_t* s, ostream* os) { PrintCStringTo(s, os); }
421void PrintTo(
const char16_t* s, ostream* os) { PrintCStringTo(s, os); }
423void PrintTo(
const char32_t* s, ostream* os) { PrintCStringTo(s, os); }
431#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
433void PrintTo(
const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
438bool ContainsUnprintableControlCodes(
const char* str,
size_t length) {
439 const unsigned char *s =
reinterpret_cast<const unsigned char *
>(str);
441 for (
size_t i = 0;
i < length;
i++) {
442 unsigned char ch = *s++;
443 if (std::iscntrl(
ch)) {
457bool IsUTF8TrailByte(
unsigned char t) {
return 0x80 <= t && t<= 0xbf; }
459bool IsValidUTF8(
const char* str,
size_t length) {
460 const unsigned char *s =
reinterpret_cast<const unsigned char *
>(str);
462 for (
size_t i = 0;
i < length;) {
463 unsigned char lead = s[
i++];
470 }
else if (lead <= 0xdf && (
i + 1) <= length && IsUTF8TrailByte(s[
i])) {
472 }
else if (0xe0 <= lead && lead <= 0xef && (
i + 2) <= length &&
473 IsUTF8TrailByte(s[
i]) &&
474 IsUTF8TrailByte(s[
i + 1]) &&
476 (lead != 0xe0 || s[
i] >= 0xa0) &&
477 (lead != 0xed || s[
i] < 0xa0)) {
479 }
else if (0xf0 <= lead && lead <= 0xf4 && (
i + 3) <= length &&
480 IsUTF8TrailByte(s[
i]) &&
481 IsUTF8TrailByte(s[
i + 1]) &&
482 IsUTF8TrailByte(s[
i + 2]) &&
484 (lead != 0xf0 || s[
i] >= 0x90) &&
485 (lead != 0xf4 || s[
i] < 0x90)) {
494void ConditionalPrintAsText(
const char* str,
size_t length, ostream* os) {
495 if (!ContainsUnprintableControlCodes(str, length) &&
496 IsValidUTF8(str, length)) {
497 *os <<
"\n As Text: \"" << str <<
"\"";
504 if (PrintCharsAsStringTo(s.data(), s.size(), os) ==
kHexEscape) {
506 ConditionalPrintAsText(s.data(), s.size(), os);
512void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
513 PrintCharsAsStringTo(s.data(), s.size(), os);
518 PrintCharsAsStringTo(s.data(), s.size(), os);
522 PrintCharsAsStringTo(s.data(), s.size(), os);
525#if GTEST_HAS_STD_WSTRING
526void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
527 PrintCharsAsStringTo(s.data(), s.size(), os);
#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
bool IsPrintableAscii(char32_t c)
GTEST_API_ void PrintU32StringTo(const ::std::u32string &s, ::std::ostream *os)
GTEST_API_ void PrintStringTo(const ::std::string &s, ::std::ostream *os)
GTEST_API_ void PrintBytesInObjectTo(const unsigned char *obj_bytes, size_t count, ::std::ostream *os)
GTEST_API_ void PrintU16StringTo(const ::std::u16string &s, ::std::ostream *os)
void UniversalPrintArray(const T *begin, size_t len, ::std::ostream *os)
void PrintTo(const T &value, ::std::ostream *os)
void PrintCharAndCodeTo(Char c, ostream *os)
static std::string FormatHexInt(int value)