1735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Copyright 2007, Google Inc. 2735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// All rights reserved. 3735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 4735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Redistribution and use in source and binary forms, with or without 5735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// modification, are permitted provided that the following conditions are 6735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// met: 7735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 8735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// * Redistributions of source code must retain the above copyright 9735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// notice, this list of conditions and the following disclaimer. 10735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// * Redistributions in binary form must reproduce the above 11735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// copyright notice, this list of conditions and the following disclaimer 12735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// in the documentation and/or other materials provided with the 13735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// distribution. 14735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// * Neither the name of Google Inc. nor the names of its 15735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// contributors may be used to endorse or promote products derived from 16735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// this software without specific prior written permission. 17735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 18735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 30735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Author: wan@google.com (Zhanyong Wan) 31735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 32735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Google Test - The Google C++ Testing Framework 33735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 34735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// This file implements a universal value printer that can print a 35735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// value of any type T: 36735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 37735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); 38735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 39735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// It uses the << operator when possible, and prints the bytes in the 40735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// object otherwise. A user can override its behavior for a class 41735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// type Foo by defining either operator<<(::std::ostream&, const Foo&) 42735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that 43735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// defines Foo. 44735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 45735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include "gtest/gtest-printers.h" 46735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include <ctype.h> 47735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include <stdio.h> 48735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include <ostream> // NOLINT 49735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include <string> 50735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#include "gtest/internal/gtest-port.h" 51735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 52735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnernamespace testing { 53735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 54735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnernamespace { 55735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 56735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerusing ::std::ostream; 57735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 58735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a segment of bytes in the given object. 59735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, 60735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner size_t count, ostream* os) { 61735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner char text[5] = ""; 62735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner for (size_t i = 0; i != count; i++) { 63735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const size_t j = start + i; 64735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (i != 0) { 65735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Organizes the bytes into groups of 2 for easy parsing by 66735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // human. 67735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if ((j % 2) == 0) 68735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ' '; 69735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner else 70735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << '-'; 71735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 72735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); 73735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << text; 74735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 75735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 76735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 77735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints the bytes in the given value to the given ostream. 78735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, 79735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner ostream* os) { 80735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Tells the user how big the object is. 81735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << count << "-byte object <"; 82735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 83735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const size_t kThreshold = 132; 84735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const size_t kChunkSize = 64; 85735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // If the object size is bigger than kThreshold, we'll have to omit 86735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // some details by printing only the first and the last kChunkSize 87735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // bytes. 88735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // TODO(wan): let the user control the threshold using a flag. 89735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (count < kThreshold) { 90735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); 91735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } else { 92735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); 93735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << " ... "; 94735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Rounds up to 2-byte boundary. 95735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const size_t resume_pos = (count - kChunkSize + 1)/2*2; 96735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); 97735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 98735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ">"; 99735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 100735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 101735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} // namespace 102735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 103735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnernamespace internal2 { 104735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 105735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Delegates to PrintBytesInObjectToImpl() to print the bytes in the 106735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// given object. The delegation simplifies the implementation, which 107735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// uses the << operator and thus is easier done outside of the 108735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// ::testing::internal namespace, which contains a << operator that 109735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// sometimes conflicts with the one in STL. 110735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, 111735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner ostream* os) { 112735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintBytesInObjectToImpl(obj_bytes, count, os); 113735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 114735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 115735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} // namespace internal2 116735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 117735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnernamespace internal { 118735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 119735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Depending on the value of a char (or wchar_t), we print it in one 120735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// of three formats: 121735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), 122735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// - as a hexidecimal escape sequence (e.g. '\x7F'), or 123735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// - as a special escape sequence (e.g. '\r', '\n'). 124735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerenum CharFormat { 125735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner kAsIs, 126735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner kHexEscape, 127735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner kSpecialEscape 128735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner}; 129735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 130735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Returns true if c is a printable ASCII character. We test the 131735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// value of c directly instead of calling isprint(), which is buggy on 132735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Windows Mobile. 133735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerinline bool IsPrintableAscii(wchar_t c) { 134735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return 0x20 <= c && c <= 0x7E; 135735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 136735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 137735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a wide or narrow char c as a character literal without the 138735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// quotes, escaping it when necessary; returns how c was formatted. 139735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// The template argument UnsignedChar is the unsigned version of Char, 140735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// which is the type of c. 141735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnertemplate <typename UnsignedChar, typename Char> 142735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerstatic CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { 143735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner switch (static_cast<wchar_t>(c)) { 144735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\0': 145735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\0"; 146735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 147735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\'': 148735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\'"; 149735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 150735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\\': 151735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\\\"; 152735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 153735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\a': 154735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\a"; 155735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 156735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\b': 157735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\b"; 158735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 159735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\f': 160735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\f"; 161735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 162735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\n': 163735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\n"; 164735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 165735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\r': 166735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\r"; 167735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 168735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\t': 169735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\t"; 170735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 171735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\v': 172735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\v"; 173735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner break; 174735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner default: 175735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (IsPrintableAscii(c)) { 176735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << static_cast<char>(c); 177735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return kAsIs; 178735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } else { 179735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c)); 180735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return kHexEscape; 181735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 182735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 183735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return kSpecialEscape; 184735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 185735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 186735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a wchar_t c as if it's part of a string literal, escaping it when 187735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// necessary; returns how c was formatted. 188735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerstatic CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { 189735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner switch (c) { 190735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'\'': 191735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "'"; 192735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return kAsIs; 193735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner case L'"': 194735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\\\""; 195735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return kSpecialEscape; 196735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner default: 197735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return PrintAsCharLiteralTo<wchar_t>(c, os); 198735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 199735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 200735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 201735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a char c as if it's part of a string literal, escaping it when 202735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// necessary; returns how c was formatted. 203735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerstatic CharFormat PrintAsStringLiteralTo(char c, ostream* os) { 204735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return PrintAsStringLiteralTo( 205735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner static_cast<wchar_t>(static_cast<unsigned char>(c)), os); 206735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 207735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 208735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a wide or narrow character c and its code. '\0' is printed 209735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// as "'\\0'", other unprintable characters are also properly escaped 210735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// using the standard C++ escape sequence. The template argument 211735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// UnsignedChar is the unsigned version of Char, which is the type of c. 212735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnertemplate <typename UnsignedChar, typename Char> 213735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintCharAndCodeTo(Char c, ostream* os) { 214735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // First, print c as a literal in the most readable form we can find. 215735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ((sizeof(c) > 1) ? "L'" : "'"); 216735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); 217735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "'"; 218735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 219735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // To aid user debugging, we also print c's code in decimal, unless 220735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // it's 0 (in which case c was printed as '\\0', making the code 221735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // obvious). 222735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (c == 0) 223735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return; 224735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << " (" << static_cast<int>(c); 225735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 226735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // For more convenience, we print c's code again in hexidecimal, 227735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // unless c was already printed in the form '\x##' or the code is in 228735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // [1, 9]. 229735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (format == kHexEscape || (1 <= c && c <= 9)) { 230735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Do nothing. 231735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } else { 232735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c)); 233735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 234735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ")"; 235735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 236735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 237735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintTo(unsigned char c, ::std::ostream* os) { 238735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharAndCodeTo<unsigned char>(c, os); 239735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 240735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintTo(signed char c, ::std::ostream* os) { 241735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharAndCodeTo<unsigned char>(c, os); 242735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 243735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 244735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a wchar_t as a symbol if it is printable or as its internal 245735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// code otherwise and also as its code. L'\0' is printed as "L'\\0'". 246735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintTo(wchar_t wc, ostream* os) { 247735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharAndCodeTo<wchar_t>(wc, os); 248735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 249735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 250735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints the given array of characters to the ostream. CharType must be either 251735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// char or wchar_t. 252735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// The array starts at begin, the length is len, it may include '\0' characters 253735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// and may not be NUL-terminated. 254735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnertemplate <typename CharType> 255735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerstatic void PrintCharsAsStringTo( 256735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const CharType* begin, size_t len, ostream* os) { 257735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; 258735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << kQuoteBegin; 259735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner bool is_previous_hex = false; 260735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner for (size_t index = 0; index < len; ++index) { 261735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const CharType cur = begin[index]; 262735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (is_previous_hex && IsXDigit(cur)) { 263735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Previous character is of '\x..' form and this character can be 264735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // interpreted as another hexadecimal digit in its number. Break string to 265735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // disambiguate. 266735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\" " << kQuoteBegin; 267735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 268735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; 269735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 270735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "\""; 271735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 272735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 273735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a (const) char/wchar_t array of 'len' elements, starting at address 274735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 'begin'. CharType must be either char or wchar_t. 275735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnertemplate <typename CharType> 276735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnerstatic void UniversalPrintCharArray( 277735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner const CharType* begin, size_t len, ostream* os) { 278735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // The code 279735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // const char kFoo[] = "foo"; 280735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // generates an array of 4, not 3, elements, with the last one being '\0'. 281735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // 282735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // Therefore when printing a char array, we don't print the last element if 283735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // it's '\0', such that the output matches the string literal as it's 284735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // written in the source code. 285735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (len > 0 && begin[len - 1] == '\0') { 286735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(begin, len - 1, os); 287735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner return; 288735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 289735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 290735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // If, however, the last element in the array is not '\0', e.g. 291735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // const char kFoo[] = { 'f', 'o', 'o' }; 292735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // we must print the entire array. We also print a message to indicate 293735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner // that the array is not NUL-terminated. 294735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(begin, len, os); 295735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << " (no terminating NUL)"; 296735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 297735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 298735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a (const) char array of 'len' elements, starting at address 'begin'. 299735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid UniversalPrintArray(const char* begin, size_t len, ostream* os) { 300735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner UniversalPrintCharArray(begin, len, os); 301735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 302735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 303735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a (const) wchar_t array of 'len' elements, starting at address 304735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// 'begin'. 305735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { 306735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner UniversalPrintCharArray(begin, len, os); 307735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 308735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 309735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints the given C string to the ostream. 310735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintTo(const char* s, ostream* os) { 311735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (s == NULL) { 312735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "NULL"; 313735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } else { 314735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ImplicitCast_<const void*>(s) << " pointing to "; 315735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s, strlen(s), os); 316735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 317735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 318735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 319735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// MSVC compiler can be configured to define whar_t as a typedef 320735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// of unsigned short. Defining an overload for const wchar_t* in that case 321735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// would cause pointers to unsigned shorts be printed as wide strings, 322735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// possibly accessing more memory than intended and causing invalid 323735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when 324735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// wchar_t is implemented as a native type. 325735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 326735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints the given wide C string to the ostream. 327735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintTo(const wchar_t* s, ostream* os) { 328735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner if (s == NULL) { 329735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << "NULL"; 330735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } else { 331735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner *os << ImplicitCast_<const void*>(s) << " pointing to "; 332735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s, wcslen(s), os); 333735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner } 334735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 335735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#endif // wchar_t is native 336735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 337735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a ::string object. 338735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#if GTEST_HAS_GLOBAL_STRING 339735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintStringTo(const ::string& s, ostream* os) { 340735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s.data(), s.size(), os); 341735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 342735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#endif // GTEST_HAS_GLOBAL_STRING 343735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 344735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintStringTo(const ::std::string& s, ostream* os) { 345735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s.data(), s.size(), os); 346735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 347735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 348735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner// Prints a ::wstring object. 349735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#if GTEST_HAS_GLOBAL_WSTRING 350735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintWideStringTo(const ::wstring& s, ostream* os) { 351735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s.data(), s.size(), os); 352735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 353735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#endif // GTEST_HAS_GLOBAL_WSTRING 354735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 355735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#if GTEST_HAS_STD_WSTRING 356735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turnervoid PrintWideStringTo(const ::std::wstring& s, ostream* os) { 357735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner PrintCharsAsStringTo(s.data(), s.size(), os); 358735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} 359735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner#endif // GTEST_HAS_STD_WSTRING 360735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 361735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} // namespace internal 362735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner 363735d57d5d1c055db9e0ef28857e8dc7b3d7d6b9bDavid 'Digit' Turner} // namespace testing 364