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
34 namespace WTF {
35
36 class CString;
37 class String;
38
39 class PrintStream {
40 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(PrintStream);
41 public:
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>
print(const T & value)53 void print(const T& value)
54 {
55 printInternal(*this, value);
56 }
57
58 template<typename T1, typename T2>
print(const T1 & value1,const T2 & value2)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>
print(const T1 & value1,const T2 & value2,const T3 & value3)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>
print(const T1 & value1,const T2 & value2,const T3 & value3,const T4 & value4)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>
print(const T1 & value1,const T2 & value2,const T3 & value3,const T4 & value4,const T5 & value5)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>
print(const T1 & value1,const T2 & value2,const T3 & value3,const T4 & value4,const T5 & value5,const T6 & value6)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>
print(const T1 & value1,const T2 & value2,const T3 & value3,const T4 & value4,const T5 & value5,const T6 & value6,const T7 & value7)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>
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)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>
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)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>
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)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>
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)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>
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)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>
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)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
209 void printInternal(PrintStream&, const char*);
210 void printInternal(PrintStream&, const CString&);
211 void printInternal(PrintStream&, const String&);
printInternal(PrintStream & out,char * value)212 inline void printInternal(PrintStream& out, char* value) { printInternal(out, static_cast<const char*>(value)); }
printInternal(PrintStream & out,CString & value)213 inline void printInternal(PrintStream& out, CString& value) { printInternal(out, static_cast<const CString&>(value)); }
printInternal(PrintStream & out,String & value)214 inline void printInternal(PrintStream& out, String& value) { printInternal(out, static_cast<const String&>(value)); }
215 void printInternal(PrintStream&, bool);
216 void printInternal(PrintStream&, int);
217 void printInternal(PrintStream&, unsigned);
218 void printInternal(PrintStream&, long);
219 void printInternal(PrintStream&, unsigned long);
220 void printInternal(PrintStream&, long long);
221 void printInternal(PrintStream&, unsigned long long);
222 void printInternal(PrintStream&, float);
223 void printInternal(PrintStream&, double);
224
225 template<typename T>
printInternal(PrintStream & out,const T & value)226 void 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.
268 void dumpCharacter(PrintStream&, char);
269 MAKE_PRINT_ADAPTOR(CharacterDump, char, dumpCharacter);
270
271 template<typename T>
272 class PointerDump {
273 public:
PointerDump(const T * ptr)274 PointerDump(const T* ptr)
275 : m_ptr(ptr)
276 {
277 }
278
dump(PrintStream & out)279 void dump(PrintStream& out) const
280 {
281 if (m_ptr)
282 printInternal(out, *m_ptr);
283 else
284 out.print("(null)");
285 }
286 private:
287 const T* m_ptr;
288 };
289
290 template<typename T>
pointerDump(const T * ptr)291 PointerDump<T> pointerDump(const T* ptr) { return PointerDump<T>(ptr); }
292
293 } // namespace WTF
294
295 using WTF::CharacterDump;
296 using WTF::PointerDump;
297 using WTF::PrintStream;
298 using WTF::pointerDump;
299
300 #endif // PrintStream_h
301
302