Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / TracedValue.cpp
blob96e4010eea705c80a66227f83369063a9e257dbc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "config.h"
7 #include "platform/TracedValue.h"
9 #include "platform/Decimal.h"
10 #include "platform/JSONValues.h"
11 #include "wtf/HashMap.h"
12 #include "wtf/text/StringBuilder.h"
13 #include "wtf/text/StringHash.h"
15 namespace blink {
17 namespace {
19 String threadSafeCopy(const String& string)
21 RefPtr<StringImpl> copy(string.impl());
22 if (string.isSafeToSendToAnotherThread())
23 return string;
24 return string.isolatedCopy();
27 } // namespace
29 // InternalValue and its subclasses are JSON like objects which TracedValue
30 // internally uses. We don't use JSONValues because we want to count how much
31 // memory TracedValue uses.
32 // TODO(bashi): InternalValue should use an allocator which counts allocation
33 // size as tracing overhead.
34 class InternalValue : public RefCounted<InternalValue> {
35 public:
36 typedef enum {
37 TypeNone,
38 TypeNumber,
39 TypeBoolean,
40 TypeString,
41 TypeArray,
42 TypeDictionary,
43 } Type;
44 virtual ~InternalValue() { }
45 virtual Type type()
47 ASSERT_NOT_REACHED();
48 return TypeNone;
50 virtual void toJSON(StringBuilder* builder)
52 ASSERT_NOT_REACHED();
56 class TracedNumberValue : public InternalValue {
57 public:
58 static PassRefPtr<TracedNumberValue> create(double value)
60 return adoptRef(new TracedNumberValue(value));
62 virtual ~TracedNumberValue() { }
63 virtual Type type() { return TypeNumber; }
64 virtual void toJSON(StringBuilder* builder)
66 builder->append(Decimal::fromDouble(m_value).toString());
69 private:
70 explicit TracedNumberValue(double value) : m_value(value) { }
71 double m_value;
74 class TracedBooleanValue : public InternalValue {
75 public:
76 static PassRefPtr<TracedBooleanValue> create(bool value)
78 return adoptRef(new TracedBooleanValue(value));
80 virtual ~TracedBooleanValue() { }
81 virtual Type type() { return TypeBoolean; }
82 virtual void toJSON(StringBuilder* builder)
84 builder->append(m_value ? "true" : "false");
87 private:
88 explicit TracedBooleanValue(bool value) : m_value(value) { }
89 bool m_value;
92 class TracedStringValue : public InternalValue {
93 public:
94 static PassRefPtr<TracedStringValue> create(String value)
96 return adoptRef(new TracedStringValue(value));
98 virtual ~TracedStringValue() { }
99 virtual Type type() { return TypeString; }
100 virtual void toJSON(StringBuilder* builder)
102 doubleQuoteStringForJSON(m_value, builder);
105 private:
106 explicit TracedStringValue(String value) : m_value(threadSafeCopy(value)) { }
107 String m_value;
110 class TracedArrayValue : public InternalValue {
111 public:
112 static PassRefPtr<TracedArrayValue> create()
114 return adoptRef(new TracedArrayValue());
116 virtual ~TracedArrayValue() { }
117 virtual Type type() { return TypeArray; }
118 virtual void toJSON(StringBuilder* builder)
120 builder->append('[');
121 for (TracedValueVector::const_iterator it = m_value.begin(); it != m_value.end(); ++it) {
122 if (it != m_value.begin())
123 builder->append(',');
124 (*it)->toJSON(builder);
126 builder->append(']');
128 void push(PassRefPtr<InternalValue> value) { m_value.append(value); }
130 private:
131 TracedArrayValue() { }
132 TracedValueVector m_value;
135 class TracedDictionaryValue : public InternalValue {
136 public:
137 static PassRefPtr<TracedDictionaryValue> create()
139 return adoptRef(new TracedDictionaryValue());
141 virtual ~TracedDictionaryValue() { }
142 virtual Type type() { return TypeDictionary; }
143 virtual void toJSON(StringBuilder* builder)
145 builder->append('{');
146 for (size_t i = 0; i < m_order.size(); ++i) {
147 TracedValueHashMap::const_iterator it = m_value.find(m_order[i]);
148 if (i)
149 builder->append(',');
150 doubleQuoteStringForJSON(it->key, builder);
151 builder->append(':');
152 it->value->toJSON(builder);
154 builder->append('}');
156 void set(const char* name, PassRefPtr<InternalValue> value)
158 String nameString = String(name);
159 if (m_value.set(nameString, value).isNewEntry)
160 m_order.append(nameString);
163 private:
164 TracedDictionaryValue() { }
165 TracedValueHashMap m_value;
166 Vector<String> m_order;
169 PassRefPtr<TracedValue> TracedValue::create()
171 return adoptRef(new TracedValue());
174 TracedValue::TracedValue()
176 m_stack.append(TracedDictionaryValue::create());
179 TracedValue::~TracedValue()
181 ASSERT(m_stack.size() == 1);
184 void TracedValue::setInteger(const char* name, int value)
186 currentDictionary()->set(name, TracedNumberValue::create(value));
189 void TracedValue::setDouble(const char* name, double value)
191 currentDictionary()->set(name, TracedNumberValue::create(value));
194 void TracedValue::setBoolean(const char* name, bool value)
196 currentDictionary()->set(name, TracedBooleanValue::create(value));
199 void TracedValue::setString(const char* name, const String& value)
201 currentDictionary()->set(name, TracedStringValue::create(value));
204 void TracedValue::beginDictionary(const char* name)
206 RefPtr<TracedDictionaryValue> dictionary = TracedDictionaryValue::create();
207 currentDictionary()->set(name, dictionary);
208 m_stack.append(dictionary);
211 void TracedValue::beginArray(const char* name)
213 RefPtr<TracedArrayValue> array = TracedArrayValue::create();
214 currentDictionary()->set(name, array);
215 m_stack.append(array);
218 void TracedValue::endDictionary()
220 ASSERT(m_stack.size() > 1);
221 ASSERT(currentDictionary());
222 m_stack.removeLast();
225 void TracedValue::pushInteger(int value)
227 currentArray()->push(TracedNumberValue::create(value));
230 void TracedValue::pushDouble(double value)
232 currentArray()->push(TracedNumberValue::create(value));
235 void TracedValue::pushBoolean(bool value)
237 currentArray()->push(TracedBooleanValue::create(value));
240 void TracedValue::pushString(const String& value)
242 currentArray()->push(TracedStringValue::create(value));
245 void TracedValue::beginArray()
247 RefPtr<TracedArrayValue> array = TracedArrayValue::create();
248 currentArray()->push(array);
249 m_stack.append(array);
252 void TracedValue::beginDictionary()
254 RefPtr<TracedDictionaryValue> dictionary = TracedDictionaryValue::create();
255 currentArray()->push(dictionary);
256 m_stack.append(dictionary);
259 void TracedValue::endArray()
261 ASSERT(m_stack.size() > 1);
262 ASSERT(currentArray());
263 m_stack.removeLast();
266 String TracedValue::asTraceFormat() const
268 ASSERT(m_stack.size() == 1);
269 StringBuilder builder;
270 m_stack.first()->toJSON(&builder);
271 return builder.toString();
274 TracedDictionaryValue* TracedValue::currentDictionary() const
276 ASSERT(!m_stack.isEmpty());
277 ASSERT(m_stack.last()->type() == InternalValue::TypeDictionary);
278 return static_cast<TracedDictionaryValue*>(m_stack.last().get());
281 TracedArrayValue* TracedValue::currentArray() const
283 ASSERT(!m_stack.isEmpty());
284 ASSERT(m_stack.last()->type() == InternalValue::TypeArray);
285 return static_cast<TracedArrayValue*>(m_stack.last().get());