c2f2ef275688ec4bfed33d3aa9ebca93556b56c3
[WebKit-https.git] / Source / WTF / wtf / text / TextStream.cpp
1 /*
2  * Copyright (C) 2004, 2008, 2010 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 #include "config.h"
27 #include "TextStream.h"
28
29 #include <wtf/MathExtras.h>
30 #include <wtf/StringExtras.h>
31 #include <wtf/text/WTFString.h>
32
33 namespace WTF {
34
35 static const size_t printBufferSize = 100; // large enough for any integer or floating point value in string format, including trailing null character
36
37 static inline bool hasFractions(double val)
38 {
39     static const double s_epsilon = 0.0001;
40     int ival = static_cast<int>(val);
41     double dval = static_cast<double>(ival);
42     return fabs(val - dval) > s_epsilon;
43 }
44
45 TextStream& TextStream::operator<<(bool b)
46 {
47     return *this << (b ? "1" : "0");
48 }
49
50 TextStream& TextStream::operator<<(int i)
51 {
52     m_text.appendNumber(i);
53     return *this;
54 }
55
56 TextStream& TextStream::operator<<(unsigned i)
57 {
58     m_text.appendNumber(i);
59     return *this;
60 }
61
62 TextStream& TextStream::operator<<(long i)
63 {
64     m_text.appendNumber(i);
65     return *this;
66 }
67
68 TextStream& TextStream::operator<<(unsigned long i)
69 {
70     m_text.appendNumber(i);
71     return *this;
72 }
73
74 TextStream& TextStream::operator<<(long long i)
75 {
76     m_text.appendNumber(i);
77     return *this;
78 }
79
80 TextStream& TextStream::operator<<(unsigned long long i)
81 {
82     m_text.appendNumber(i);
83     return *this;
84 }
85
86 TextStream& TextStream::operator<<(float f)
87 {
88     if (m_formattingFlags & Formatting::NumberRespectingIntegers)
89         return *this << FormatNumberRespectingIntegers(f);
90
91     m_text.appendFixedWidthNumber(f, 2);
92     return *this;
93 }
94
95 TextStream& TextStream::operator<<(double d)
96 {
97     if (m_formattingFlags & Formatting::NumberRespectingIntegers)
98         return *this << FormatNumberRespectingIntegers(d);
99
100     m_text.appendFixedWidthNumber(d, 2);
101     return *this;
102 }
103
104 TextStream& TextStream::operator<<(const char* string)
105 {
106     m_text.append(string);
107     return *this;
108 }
109
110 TextStream& TextStream::operator<<(const void* p)
111 {
112     char buffer[printBufferSize];
113     snprintf(buffer, sizeof(buffer) - 1, "%p", p);
114     return *this << buffer;
115 }
116
117 TextStream& TextStream::operator<<(const String& string)
118 {
119     m_text.append(string);
120     return *this;
121 }
122
123 TextStream& TextStream::operator<<(const FormatNumberRespectingIntegers& numberToFormat)
124 {
125     if (hasFractions(numberToFormat.value)) {
126         m_text.appendFixedWidthNumber(numberToFormat.value, 2);
127         return *this;
128     }
129
130     m_text.appendNumber(static_cast<int>(numberToFormat.value));
131     return *this;
132 }
133
134 String TextStream::release()
135 {
136     String result = m_text.toString();
137     m_text.clear();
138     return result;
139 }
140
141 void TextStream::startGroup()
142 {
143     TextStream& ts = *this;
144
145     if (m_multiLineMode) {
146         ts << "\n";
147         ts.writeIndent();
148         ts << "(";
149         ts.increaseIndent();
150     } else
151         ts << " (";
152 }
153
154 void TextStream::endGroup()
155 {
156     TextStream& ts = *this;
157     ts << ")";
158     if (m_multiLineMode)
159         ts.decreaseIndent();
160 }
161
162 void TextStream::nextLine()
163 {
164     TextStream& ts = *this;
165     if (m_multiLineMode) {
166         ts << "\n";
167         ts.writeIndent();
168     } else
169         ts << " ";
170 }
171
172 void TextStream::writeIndent()
173 {
174     if (m_multiLineMode)
175         WTF::writeIndent(*this, m_indent);
176 }
177
178 void writeIndent(TextStream& ts, int indent)
179 {
180     for (int i = 0; i < indent; ++i)
181         ts << "  ";
182 }
183
184 }