• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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