OLD | NEW |
(Empty) | |
| 1 // Copyright 2007, Google Inc. |
| 2 // All rights reserved. |
| 3 // |
| 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are |
| 6 // met: |
| 7 // |
| 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above |
| 11 // copyright notice, this list of conditions and the following disclaimer |
| 12 // in the documentation and/or other materials provided with the |
| 13 // distribution. |
| 14 // * Neither the name of Google Inc. nor the names of its |
| 15 // contributors may be used to endorse or promote products derived from |
| 16 // this software without specific prior written permission. |
| 17 // |
| 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 // |
| 30 // Author: wan@google.com (Zhanyong Wan) |
| 31 |
| 32 // Google Mock - a framework for writing C++ mock classes. |
| 33 // |
| 34 // This file implements a universal value printer that can print a |
| 35 // value of any type T: |
| 36 // |
| 37 // void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); |
| 38 // |
| 39 // It uses the << operator when possible, and prints the bytes in the |
| 40 // object otherwise. A user can override its behavior for a class |
| 41 // type Foo by defining either operator<<(::std::ostream&, const Foo&) |
| 42 // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that |
| 43 // defines Foo. |
| 44 |
| 45 #include <gmock/gmock-printers.h> |
| 46 #include <ctype.h> |
| 47 #include <stdio.h> |
| 48 #include <ostream> // NOLINT |
| 49 #include <string> |
| 50 #include <gmock/internal/gmock-port.h> |
| 51 |
| 52 namespace testing { |
| 53 |
| 54 namespace { |
| 55 |
| 56 using ::std::ostream; |
| 57 |
| 58 #ifdef _WIN32_WCE |
| 59 #define snprintf _snprintf |
| 60 #elif GTEST_OS_WINDOWS |
| 61 #define snprintf _snprintf_s |
| 62 #endif |
| 63 |
| 64 // Prints a segment of bytes in the given object. |
| 65 void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, |
| 66 size_t count, ostream* os) { |
| 67 char text[5] = ""; |
| 68 for (size_t i = 0; i != count; i++) { |
| 69 const size_t j = start + i; |
| 70 if (i != 0) { |
| 71 // Organizes the bytes into groups of 2 for easy parsing by |
| 72 // human. |
| 73 if ((j % 2) == 0) { |
| 74 *os << " "; |
| 75 } |
| 76 } |
| 77 snprintf(text, sizeof(text), "%02X", obj_bytes[j]); |
| 78 *os << text; |
| 79 } |
| 80 } |
| 81 |
| 82 // Prints the bytes in the given value to the given ostream. |
| 83 void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, |
| 84 ostream* os) { |
| 85 // Tells the user how big the object is. |
| 86 *os << count << "-byte object <"; |
| 87 |
| 88 const size_t kThreshold = 132; |
| 89 const size_t kChunkSize = 64; |
| 90 // If the object size is bigger than kThreshold, we'll have to omit |
| 91 // some details by printing only the first and the last kChunkSize |
| 92 // bytes. |
| 93 // TODO(wan): let the user control the threshold using a flag. |
| 94 if (count < kThreshold) { |
| 95 PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); |
| 96 } else { |
| 97 PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); |
| 98 *os << " ... "; |
| 99 // Rounds up to 2-byte boundary. |
| 100 const size_t resume_pos = (count - kChunkSize + 1)/2*2; |
| 101 PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); |
| 102 } |
| 103 *os << ">"; |
| 104 } |
| 105 |
| 106 } // namespace |
| 107 |
| 108 namespace internal2 { |
| 109 |
| 110 // Delegates to PrintBytesInObjectToImpl() to print the bytes in the |
| 111 // given object. The delegation simplifies the implementation, which |
| 112 // uses the << operator and thus is easier done outside of the |
| 113 // ::testing::internal namespace, which contains a << operator that |
| 114 // sometimes conflicts with the one in STL. |
| 115 void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, |
| 116 ostream* os) { |
| 117 PrintBytesInObjectToImpl(obj_bytes, count, os); |
| 118 } |
| 119 |
| 120 } // namespace internal2 |
| 121 |
| 122 namespace internal { |
| 123 |
| 124 // Prints a wide char as a char literal without the quotes, escaping it |
| 125 // when necessary. |
| 126 static void PrintAsWideCharLiteralTo(wchar_t c, ostream* os) { |
| 127 switch (c) { |
| 128 case L'\0': |
| 129 *os << "\\0"; |
| 130 break; |
| 131 case L'\'': |
| 132 *os << "\\'"; |
| 133 break; |
| 134 case L'\?': |
| 135 *os << "\\?"; |
| 136 break; |
| 137 case L'\\': |
| 138 *os << "\\\\"; |
| 139 break; |
| 140 case L'\a': |
| 141 *os << "\\a"; |
| 142 break; |
| 143 case L'\b': |
| 144 *os << "\\b"; |
| 145 break; |
| 146 case L'\f': |
| 147 *os << "\\f"; |
| 148 break; |
| 149 case L'\n': |
| 150 *os << "\\n"; |
| 151 break; |
| 152 case L'\r': |
| 153 *os << "\\r"; |
| 154 break; |
| 155 case L'\t': |
| 156 *os << "\\t"; |
| 157 break; |
| 158 case L'\v': |
| 159 *os << "\\v"; |
| 160 break; |
| 161 default: |
| 162 // Checks whether c is printable or not. Printable characters are in |
| 163 // the range [0x20,0x7E]. |
| 164 // We test the value of c directly instead of calling isprint(), as |
| 165 // isprint() is buggy on Windows mobile. |
| 166 if (0x20 <= c && c <= 0x7E) { |
| 167 *os << static_cast<char>(c); |
| 168 } else { |
| 169 // Buffer size enough for the maximum number of digits and \0. |
| 170 char text[2 * sizeof(unsigned long) + 1] = ""; |
| 171 snprintf(text, sizeof(text), "%lX", static_cast<unsigned long>(c)); |
| 172 *os << "\\x" << text; |
| 173 } |
| 174 } |
| 175 } |
| 176 |
| 177 // Prints a char as if it's part of a string literal, escaping it when |
| 178 // necessary. |
| 179 static void PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { |
| 180 switch (c) { |
| 181 case L'\'': |
| 182 *os << "'"; |
| 183 break; |
| 184 case L'"': |
| 185 *os << "\\\""; |
| 186 break; |
| 187 default: |
| 188 PrintAsWideCharLiteralTo(c, os); |
| 189 } |
| 190 } |
| 191 |
| 192 // Prints a char as a char literal without the quotes, escaping it |
| 193 // when necessary. |
| 194 static void PrintAsCharLiteralTo(char c, ostream* os) { |
| 195 PrintAsWideCharLiteralTo(static_cast<unsigned char>(c), os); |
| 196 } |
| 197 |
| 198 // Prints a char as if it's part of a string literal, escaping it when |
| 199 // necessary. |
| 200 static void PrintAsStringLiteralTo(char c, ostream* os) { |
| 201 PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os); |
| 202 } |
| 203 |
| 204 // Prints a char and its code. The '\0' char is printed as "'\\0'", |
| 205 // other unprintable characters are also properly escaped using the |
| 206 // standard C++ escape sequence. |
| 207 void PrintCharTo(char c, int char_code, ostream* os) { |
| 208 *os << "'"; |
| 209 PrintAsCharLiteralTo(c, os); |
| 210 *os << "'"; |
| 211 if (c != '\0') |
| 212 *os << " (" << char_code << ")"; |
| 213 } |
| 214 |
| 215 // Prints a wchar_t as a symbol if it is printable or as its internal |
| 216 // code otherwise and also as its decimal code (except for L'\0'). |
| 217 // The L'\0' char is printed as "L'\\0'". The decimal code is printed |
| 218 // as signed integer when wchar_t is implemented by the compiler |
| 219 // as a signed type and is printed as an unsigned integer when wchar_t |
| 220 // is implemented as an unsigned type. |
| 221 void PrintTo(wchar_t wc, ostream* os) { |
| 222 *os << "L'"; |
| 223 PrintAsWideCharLiteralTo(wc, os); |
| 224 *os << "'"; |
| 225 if (wc != L'\0') { |
| 226 // Type Int64 is used because it provides more storage than wchar_t thus |
| 227 // when the compiler converts signed or unsigned implementation of wchar_t |
| 228 // to Int64 it fills higher bits with either zeros or the sign bit |
| 229 // passing it to operator <<() as either signed or unsigned integer. |
| 230 *os << " (" << static_cast<Int64>(wc) << ")"; |
| 231 } |
| 232 } |
| 233 |
| 234 // Prints the given array of characters to the ostream. |
| 235 // The array starts at *begin, the length is len, it may include '\0' characters |
| 236 // and may not be null-terminated. |
| 237 static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { |
| 238 *os << "\""; |
| 239 for (size_t index = 0; index < len; ++index) { |
| 240 PrintAsStringLiteralTo(begin[index], os); |
| 241 } |
| 242 *os << "\""; |
| 243 } |
| 244 |
| 245 // Prints the given array of wide characters to the ostream. |
| 246 // The array starts at *begin, the length is len, it may include L'\0' |
| 247 // characters and may not be null-terminated. |
| 248 static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, |
| 249 ostream* os) { |
| 250 *os << "L\""; |
| 251 for (size_t index = 0; index < len; ++index) { |
| 252 PrintAsWideStringLiteralTo(begin[index], os); |
| 253 } |
| 254 *os << "\""; |
| 255 } |
| 256 |
| 257 // Prints the given C string to the ostream. |
| 258 void PrintTo(const char* s, ostream* os) { |
| 259 if (s == NULL) { |
| 260 *os << "NULL"; |
| 261 } else { |
| 262 *os << implicit_cast<const void*>(s) << " pointing to "; |
| 263 PrintCharsAsStringTo(s, strlen(s), os); |
| 264 } |
| 265 } |
| 266 |
| 267 // MSVC compiler can be configured to define whar_t as a typedef |
| 268 // of unsigned short. Defining an overload for const wchar_t* in that case |
| 269 // would cause pointers to unsigned shorts be printed as wide strings, |
| 270 // possibly accessing more memory than intended and causing invalid |
| 271 // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when |
| 272 // wchar_t is implemented as a native type. |
| 273 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) |
| 274 // Prints the given wide C string to the ostream. |
| 275 void PrintTo(const wchar_t* s, ostream* os) { |
| 276 if (s == NULL) { |
| 277 *os << "NULL"; |
| 278 } else { |
| 279 *os << implicit_cast<const void*>(s) << " pointing to "; |
| 280 PrintWideCharsAsStringTo(s, wcslen(s), os); |
| 281 } |
| 282 } |
| 283 #endif // wchar_t is native |
| 284 |
| 285 // Prints a ::string object. |
| 286 #if GTEST_HAS_GLOBAL_STRING |
| 287 void PrintStringTo(const ::string& s, ostream* os) { |
| 288 PrintCharsAsStringTo(s.data(), s.size(), os); |
| 289 } |
| 290 #endif // GTEST_HAS_GLOBAL_STRING |
| 291 |
| 292 #if GTEST_HAS_STD_STRING |
| 293 void PrintStringTo(const ::std::string& s, ostream* os) { |
| 294 PrintCharsAsStringTo(s.data(), s.size(), os); |
| 295 } |
| 296 #endif // GTEST_HAS_STD_STRING |
| 297 |
| 298 // Prints a ::wstring object. |
| 299 #if GTEST_HAS_GLOBAL_WSTRING |
| 300 void PrintWideStringTo(const ::wstring& s, ostream* os) { |
| 301 PrintWideCharsAsStringTo(s.data(), s.size(), os); |
| 302 } |
| 303 #endif // GTEST_HAS_GLOBAL_WSTRING |
| 304 |
| 305 #if GTEST_HAS_STD_WSTRING |
| 306 void PrintWideStringTo(const ::std::wstring& s, ostream* os) { |
| 307 PrintWideCharsAsStringTo(s.data(), s.size(), os); |
| 308 } |
| 309 #endif // GTEST_HAS_STD_WSTRING |
| 310 |
| 311 } // namespace internal |
| 312 |
| 313 } // namespace testing |
OLD | NEW |