1/* 2 * Copyright (C) 2012 Apple Inc. 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 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef PrintStream_h 27#define PrintStream_h 28 29#include <stdarg.h> 30#include "wtf/FastAllocBase.h" 31#include "wtf/Noncopyable.h" 32#include "wtf/StdLibExtras.h" 33 34namespace WTF { 35 36class CString; 37class String; 38 39class PrintStream { 40 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(PrintStream); 41public: 42 PrintStream(); 43 virtual ~PrintStream(); 44 45 void printf(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); 46 virtual void vprintf(const char* format, va_list) WTF_ATTRIBUTE_PRINTF(2, 0) = 0; 47 48 // Typically a no-op for many subclasses of PrintStream, this is a hint that 49 // the implementation should flush its buffers if it had not done so already. 50 virtual void flush(); 51 52 template<typename T> 53 void print(const T& value) 54 { 55 printInternal(*this, value); 56 } 57 58 template<typename T1, typename T2> 59 void print(const T1& value1, const T2& value2) 60 { 61 print(value1); 62 print(value2); 63 } 64 65 template<typename T1, typename T2, typename T3> 66 void print(const T1& value1, const T2& value2, const T3& value3) 67 { 68 print(value1); 69 print(value2); 70 print(value3); 71 } 72 73 template<typename T1, typename T2, typename T3, typename T4> 74 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4) 75 { 76 print(value1); 77 print(value2); 78 print(value3); 79 print(value4); 80 } 81 82 template<typename T1, typename T2, typename T3, typename T4, typename T5> 83 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5) 84 { 85 print(value1); 86 print(value2); 87 print(value3); 88 print(value4); 89 print(value5); 90 } 91 92 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> 93 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6) 94 { 95 print(value1); 96 print(value2); 97 print(value3); 98 print(value4); 99 print(value5); 100 print(value6); 101 } 102 103 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> 104 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7) 105 { 106 print(value1); 107 print(value2); 108 print(value3); 109 print(value4); 110 print(value5); 111 print(value6); 112 print(value7); 113 } 114 115 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> 116 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8) 117 { 118 print(value1); 119 print(value2); 120 print(value3); 121 print(value4); 122 print(value5); 123 print(value6); 124 print(value7); 125 print(value8); 126 } 127 128 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> 129 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9) 130 { 131 print(value1); 132 print(value2); 133 print(value3); 134 print(value4); 135 print(value5); 136 print(value6); 137 print(value7); 138 print(value8); 139 print(value9); 140 } 141 142 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10> 143 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10) 144 { 145 print(value1); 146 print(value2); 147 print(value3); 148 print(value4); 149 print(value5); 150 print(value6); 151 print(value7); 152 print(value8); 153 print(value9); 154 print(value10); 155 } 156 157 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11> 158 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11) 159 { 160 print(value1); 161 print(value2); 162 print(value3); 163 print(value4); 164 print(value5); 165 print(value6); 166 print(value7); 167 print(value8); 168 print(value9); 169 print(value10); 170 print(value11); 171 } 172 173 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12> 174 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12) 175 { 176 print(value1); 177 print(value2); 178 print(value3); 179 print(value4); 180 print(value5); 181 print(value6); 182 print(value7); 183 print(value8); 184 print(value9); 185 print(value10); 186 print(value11); 187 print(value12); 188 } 189 190 template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13> 191 void print(const T1& value1, const T2& value2, const T3& value3, const T4& value4, const T5& value5, const T6& value6, const T7& value7, const T8& value8, const T9& value9, const T10& value10, const T11& value11, const T12& value12, const T13& value13) 192 { 193 print(value1); 194 print(value2); 195 print(value3); 196 print(value4); 197 print(value5); 198 print(value6); 199 print(value7); 200 print(value8); 201 print(value9); 202 print(value10); 203 print(value11); 204 print(value12); 205 print(value13); 206 } 207}; 208 209void printInternal(PrintStream&, const char*); 210void printInternal(PrintStream&, const CString&); 211void printInternal(PrintStream&, const String&); 212inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); } 213inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); } 214inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); } 215void printInternal(PrintStream&, bool); 216void printInternal(PrintStream&, int); 217void printInternal(PrintStream&, unsigned); 218void printInternal(PrintStream&, long); 219void printInternal(PrintStream&, unsigned long); 220void printInternal(PrintStream&, long long); 221void printInternal(PrintStream&, unsigned long long); 222void printInternal(PrintStream&, float); 223void printInternal(PrintStream&, double); 224 225template<typename T> 226void printInternal(PrintStream& out, const T& value) 227{ 228 value.dump(out); 229} 230 231#define MAKE_PRINT_ADAPTOR(Name, Type, function) \ 232 class Name { \ 233 public: \ 234 Name(const Type& value) \ 235 : m_value(value) \ 236 { \ 237 } \ 238 void dump(PrintStream& out) const \ 239 { \ 240 function(out, m_value); \ 241 } \ 242 private: \ 243 Type m_value; \ 244 } 245 246#define MAKE_PRINT_METHOD_ADAPTOR(Name, Type, method) \ 247 class Name { \ 248 public: \ 249 Name(const Type& value) \ 250 : m_value(value) \ 251 { \ 252 } \ 253 void dump(PrintStream& out) const \ 254 { \ 255 m_value.method(out); \ 256 } \ 257 private: \ 258 const Type& m_value; \ 259 } 260 261#define MAKE_PRINT_METHOD(Type, dumpMethod, method) \ 262 MAKE_PRINT_METHOD_ADAPTOR(DumperFor_##method, Type, dumpMethod); \ 263 DumperFor_##method method() const { return DumperFor_##method(*this); } 264 265// Use an adaptor-based dumper for characters to avoid situations where 266// you've "compressed" an integer to a character and it ends up printing 267// as ASCII when you wanted it to print as a number. 268void dumpCharacter(PrintStream&, char); 269MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter); 270 271template<typename T> 272class PointerDump { 273public: 274 PointerDump(const T* ptr) 275 : m_ptr(ptr) 276 { 277 } 278 279 void dump(PrintStream& out) const 280 { 281 if (m_ptr) 282 printInternal(out, *m_ptr); 283 else 284 out.print("(null)"); 285 } 286private: 287 const T* m_ptr; 288}; 289 290template<typename T> 291PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); } 292 293} // namespace WTF 294 295using WTF::CharacterDump; 296using WTF::PointerDump; 297using WTF::PrintStream; 298using WTF::pointerDump; 299 300#endif // PrintStream_h 301 302