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.
4
5#include "config.h"
6
7#include "platform/TracedValue.h"
8
9#include "platform/JSONValues.h"
10
11namespace blink {
12
13namespace {
14
15String threadSafeCopy(const String& string)
16{
17    RefPtr<StringImpl> copy(string.impl());
18    if (string.isSafeToSendToAnotherThread())
19        return string;
20    return string.isolatedCopy();
21}
22
23}
24
25PassRefPtr<TracedValue> TracedValue::create()
26{
27    return adoptRef(new TracedValue());
28}
29
30TracedValue::TracedValue()
31{
32    m_stack.append(JSONObject::create());
33}
34
35TracedValue::~TracedValue()
36{
37    ASSERT(m_stack.size() == 1);
38}
39
40void TracedValue::setInteger(const char* name, int value)
41{
42    currentDictionary()->setNumber(name, value);
43}
44
45void TracedValue::setDouble(const char* name, double value)
46{
47    currentDictionary()->setNumber(name, value);
48}
49
50void TracedValue::setBoolean(const char* name, bool value)
51{
52    currentDictionary()->setBoolean(name, value);
53}
54
55void TracedValue::setString(const char* name, const String& value)
56{
57    currentDictionary()->setString(name, threadSafeCopy(value));
58}
59
60void TracedValue::beginDictionary(const char* name)
61{
62    RefPtr<JSONObject> dictionary = JSONObject::create();
63    currentDictionary()->setObject(name, dictionary);
64    m_stack.append(dictionary);
65}
66
67void TracedValue::beginArray(const char* name)
68{
69    RefPtr<JSONArray> array = JSONArray::create();
70    currentDictionary()->setArray(name, array);
71    m_stack.append(array);
72}
73
74void TracedValue::endDictionary()
75{
76    ASSERT(m_stack.size() > 1);
77    ASSERT(currentDictionary());
78    m_stack.removeLast();
79}
80
81void TracedValue::pushInteger(int value)
82{
83    currentArray()->pushInt(value);
84}
85
86void TracedValue::pushDouble(double value)
87{
88    currentArray()->pushNumber(value);
89}
90
91void TracedValue::pushBoolean(bool value)
92{
93    currentArray()->pushBoolean(value);
94}
95
96void TracedValue::pushString(const String& value)
97{
98    currentArray()->pushString(threadSafeCopy(value));
99}
100
101void TracedValue::beginArray()
102{
103    RefPtr<JSONArray> array = JSONArray::create();
104    currentArray()->pushArray(array);
105    m_stack.append(array);
106}
107
108void TracedValue::beginDictionary()
109{
110    RefPtr<JSONObject> dictionary = JSONObject::create();
111    currentArray()->pushObject(dictionary);
112    m_stack.append(dictionary);
113}
114
115void TracedValue::endArray()
116{
117    ASSERT(m_stack.size() > 1);
118    ASSERT(currentArray());
119    m_stack.removeLast();
120}
121
122String TracedValue::asTraceFormat() const
123{
124    ASSERT(m_stack.size() == 1);
125    return m_stack.first()->toJSONString();
126}
127
128JSONObject* TracedValue::currentDictionary() const
129{
130    ASSERT(!m_stack.isEmpty());
131    ASSERT(m_stack.last()->type() == JSONValue::TypeObject);
132    return static_cast<JSONObject*>(m_stack.last().get());
133}
134
135JSONArray* TracedValue::currentArray() const
136{
137    ASSERT(!m_stack.isEmpty());
138    ASSERT(m_stack.last()->type() == JSONValue::TypeArray);
139    return static_cast<JSONArray*>(m_stack.last().get());
140}
141
142}
143