00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "gtest/gtest-printers.h"
00046 #include <ctype.h>
00047 #include <stdio.h>
00048 #include <ostream>
00049 #include <string>
00050 #include "gtest/internal/gtest-port.h"
00051
00052 namespace testing {
00053
00054 namespace {
00055
00056 using ::std::ostream;
00057
00058
00059 void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
00060 size_t count, ostream* os) {
00061 char text[5] = "";
00062 for (size_t i = 0; i != count; i++) {
00063 const size_t j = start + i;
00064 if (i != 0) {
00065
00066
00067 if ((j % 2) == 0)
00068 *os << ' ';
00069 else
00070 *os << '-';
00071 }
00072 GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]);
00073 *os << text;
00074 }
00075 }
00076
00077
00078 void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
00079 ostream* os) {
00080
00081 *os << count << "-byte object <";
00082
00083 const size_t kThreshold = 132;
00084 const size_t kChunkSize = 64;
00085
00086
00087
00088
00089 if (count < kThreshold) {
00090 PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
00091 } else {
00092 PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
00093 *os << " ... ";
00094
00095 const size_t resume_pos = (count - kChunkSize + 1)/2*2;
00096 PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
00097 }
00098 *os << ">";
00099 }
00100
00101 }
00102
00103 namespace internal2 {
00104
00105
00106
00107
00108
00109
00110 void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
00111 ostream* os) {
00112 PrintBytesInObjectToImpl(obj_bytes, count, os);
00113 }
00114
00115 }
00116
00117 namespace internal {
00118
00119
00120
00121
00122
00123
00124 enum CharFormat {
00125 kAsIs,
00126 kHexEscape,
00127 kSpecialEscape
00128 };
00129
00130
00131
00132
00133 inline bool IsPrintableAscii(wchar_t c) {
00134 return 0x20 <= c && c <= 0x7E;
00135 }
00136
00137
00138
00139
00140
00141 template <typename UnsignedChar, typename Char>
00142 static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
00143 switch (static_cast<wchar_t>(c)) {
00144 case L'\0':
00145 *os << "\\0";
00146 break;
00147 case L'\'':
00148 *os << "\\'";
00149 break;
00150 case L'\\':
00151 *os << "\\\\";
00152 break;
00153 case L'\a':
00154 *os << "\\a";
00155 break;
00156 case L'\b':
00157 *os << "\\b";
00158 break;
00159 case L'\f':
00160 *os << "\\f";
00161 break;
00162 case L'\n':
00163 *os << "\\n";
00164 break;
00165 case L'\r':
00166 *os << "\\r";
00167 break;
00168 case L'\t':
00169 *os << "\\t";
00170 break;
00171 case L'\v':
00172 *os << "\\v";
00173 break;
00174 default:
00175 if (IsPrintableAscii(c)) {
00176 *os << static_cast<char>(c);
00177 return kAsIs;
00178 } else {
00179 *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
00180 return kHexEscape;
00181 }
00182 }
00183 return kSpecialEscape;
00184 }
00185
00186
00187
00188 static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
00189 switch (c) {
00190 case L'\'':
00191 *os << "'";
00192 return kAsIs;
00193 case L'"':
00194 *os << "\\\"";
00195 return kSpecialEscape;
00196 default:
00197 return PrintAsCharLiteralTo<wchar_t>(c, os);
00198 }
00199 }
00200
00201
00202
00203 static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
00204 return PrintAsStringLiteralTo(
00205 static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
00206 }
00207
00208
00209
00210
00211
00212 template <typename UnsignedChar, typename Char>
00213 void PrintCharAndCodeTo(Char c, ostream* os) {
00214
00215 *os << ((sizeof(c) > 1) ? "L'" : "'");
00216 const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
00217 *os << "'";
00218
00219
00220
00221
00222 if (c == 0)
00223 return;
00224 *os << " (" << static_cast<int>(c);
00225
00226
00227
00228
00229 if (format == kHexEscape || (1 <= c && c <= 9)) {
00230
00231 } else {
00232 *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
00233 }
00234 *os << ")";
00235 }
00236
00237 void PrintTo(unsigned char c, ::std::ostream* os) {
00238 PrintCharAndCodeTo<unsigned char>(c, os);
00239 }
00240 void PrintTo(signed char c, ::std::ostream* os) {
00241 PrintCharAndCodeTo<unsigned char>(c, os);
00242 }
00243
00244
00245
00246 void PrintTo(wchar_t wc, ostream* os) {
00247 PrintCharAndCodeTo<wchar_t>(wc, os);
00248 }
00249
00250
00251
00252
00253
00254 template <typename CharType>
00255 static void PrintCharsAsStringTo(
00256 const CharType* begin, size_t len, ostream* os) {
00257 const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
00258 *os << kQuoteBegin;
00259 bool is_previous_hex = false;
00260 for (size_t index = 0; index < len; ++index) {
00261 const CharType cur = begin[index];
00262 if (is_previous_hex && IsXDigit(cur)) {
00263
00264
00265
00266 *os << "\" " << kQuoteBegin;
00267 }
00268 is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
00269 }
00270 *os << "\"";
00271 }
00272
00273
00274
00275 template <typename CharType>
00276 static void UniversalPrintCharArray(
00277 const CharType* begin, size_t len, ostream* os) {
00278
00279
00280
00281
00282
00283
00284
00285 if (len > 0 && begin[len - 1] == '\0') {
00286 PrintCharsAsStringTo(begin, len - 1, os);
00287 return;
00288 }
00289
00290
00291
00292
00293
00294 PrintCharsAsStringTo(begin, len, os);
00295 *os << " (no terminating NUL)";
00296 }
00297
00298
00299 void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
00300 UniversalPrintCharArray(begin, len, os);
00301 }
00302
00303
00304
00305 void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
00306 UniversalPrintCharArray(begin, len, os);
00307 }
00308
00309
00310 void PrintTo(const char* s, ostream* os) {
00311 if (s == NULL) {
00312 *os << "NULL";
00313 } else {
00314 *os << ImplicitCast_<const void*>(s) << " pointing to ";
00315 PrintCharsAsStringTo(s, strlen(s), os);
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
00326
00327 void PrintTo(const wchar_t* s, ostream* os) {
00328 if (s == NULL) {
00329 *os << "NULL";
00330 } else {
00331 *os << ImplicitCast_<const void*>(s) << " pointing to ";
00332 PrintCharsAsStringTo(s, wcslen(s), os);
00333 }
00334 }
00335 #endif // wchar_t is native
00336
00337
00338 #if GTEST_HAS_GLOBAL_STRING
00339 void PrintStringTo(const ::string& s, ostream* os) {
00340 PrintCharsAsStringTo(s.data(), s.size(), os);
00341 }
00342 #endif // GTEST_HAS_GLOBAL_STRING
00343
00344 void PrintStringTo(const ::std::string& s, ostream* os) {
00345 PrintCharsAsStringTo(s.data(), s.size(), os);
00346 }
00347
00348
00349 #if GTEST_HAS_GLOBAL_WSTRING
00350 void PrintWideStringTo(const ::wstring& s, ostream* os) {
00351 PrintCharsAsStringTo(s.data(), s.size(), os);
00352 }
00353 #endif // GTEST_HAS_GLOBAL_WSTRING
00354
00355 #if GTEST_HAS_STD_WSTRING
00356 void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
00357 PrintCharsAsStringTo(s.data(), s.size(), os);
00358 }
00359 #endif // GTEST_HAS_STD_WSTRING
00360
00361 }
00362
00363 }