blob: 646b1f2168794fca6ec2108b085b1014a2205830 [file] [log] [blame]
yurys@chromium.org937ea9d2014-08-01 22:10:38 +09001// Copyright (c) 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
ssid89455a72015-01-27 22:14:07 +09005#include "base/trace_event/trace_event_argument.h"
yurys@chromium.org937ea9d2014-08-01 22:10:38 +09006
avi2cea4dd2015-12-24 13:03:44 +09007#include <stdint.h>
8
danakj800d2ea2015-11-25 14:29:58 +09009#include <utility>
10
primiano47c69062015-07-25 05:13:32 +090011#include "base/bits.h"
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090012#include "base/json/json_writer.h"
dchengcc8e4d82016-04-05 06:25:51 +090013#include "base/memory/ptr_util.h"
primianof5999252015-06-11 09:43:15 +090014#include "base/trace_event/trace_event_memory_overhead.h"
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090015#include "base/values.h"
16
17namespace base {
primianod6acdd22015-02-05 23:20:26 +090018namespace trace_event {
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090019
primiano9f75b242015-06-11 21:15:07 +090020namespace {
21const char kTypeStartDict = '{';
22const char kTypeEndDict = '}';
23const char kTypeStartArray = '[';
24const char kTypeEndArray = ']';
25const char kTypeBool = 'b';
26const char kTypeInt = 'i';
27const char kTypeDouble = 'd';
28const char kTypeString = 's';
29const char kTypeCStr = '*';
30
31#ifndef NDEBUG
32const bool kStackTypeDict = false;
33const bool kStackTypeArray = true;
34#define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back())
35#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size())
36#define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x)
37#define DEBUG_POP_CONTAINER() nesting_stack_.pop_back()
38#else
39#define DCHECK_CURRENT_CONTAINER_IS(x) do {} while (0)
40#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) do {} while (0)
41#define DEBUG_PUSH_CONTAINER(x) do {} while (0)
42#define DEBUG_POP_CONTAINER() do {} while (0)
43#endif
44
45inline void WriteKeyNameAsRawPtr(Pickle& pickle, const char* ptr) {
46 pickle.WriteBytes(&kTypeCStr, 1);
avi2cea4dd2015-12-24 13:03:44 +090047 pickle.WriteUInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)));
primiano9f75b242015-06-11 21:15:07 +090048}
49
jbroman5a1db872015-11-19 01:19:48 +090050inline void WriteKeyNameWithCopy(Pickle& pickle, base::StringPiece str) {
primiano9f75b242015-06-11 21:15:07 +090051 pickle.WriteBytes(&kTypeString, 1);
52 pickle.WriteString(str);
53}
54
55std::string ReadKeyName(PickleIterator& pickle_iterator) {
56 const char* type = nullptr;
57 bool res = pickle_iterator.ReadBytes(&type, 1);
58 std::string key_name;
59 if (res && *type == kTypeCStr) {
avi2cea4dd2015-12-24 13:03:44 +090060 uint64_t ptr_value = 0;
primiano9f75b242015-06-11 21:15:07 +090061 res = pickle_iterator.ReadUInt64(&ptr_value);
62 key_name = reinterpret_cast<const char*>(static_cast<uintptr_t>(ptr_value));
63 } else if (res && *type == kTypeString) {
64 res = pickle_iterator.ReadString(&key_name);
65 }
66 DCHECK(res);
67 return key_name;
68}
69} // namespace
70
71TracedValue::TracedValue() : TracedValue(0) {
72}
73
74TracedValue::TracedValue(size_t capacity) {
75 DEBUG_PUSH_CONTAINER(kStackTypeDict);
76 if (capacity)
77 pickle_.Reserve(capacity);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090078}
79
80TracedValue::~TracedValue() {
primiano9f75b242015-06-11 21:15:07 +090081 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
82 DEBUG_POP_CONTAINER();
83 DCHECK_CONTAINER_STACK_DEPTH_EQ(0u);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090084}
85
86void TracedValue::SetInteger(const char* name, int value) {
primiano9f75b242015-06-11 21:15:07 +090087 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
88 pickle_.WriteBytes(&kTypeInt, 1);
89 pickle_.WriteInt(value);
90 WriteKeyNameAsRawPtr(pickle_, name);
91}
92
jbroman5a1db872015-11-19 01:19:48 +090093void TracedValue::SetIntegerWithCopiedName(base::StringPiece name, int value) {
primiano9f75b242015-06-11 21:15:07 +090094 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
95 pickle_.WriteBytes(&kTypeInt, 1);
96 pickle_.WriteInt(value);
jbroman5a1db872015-11-19 01:19:48 +090097 WriteKeyNameWithCopy(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +090098}
99
100void TracedValue::SetDouble(const char* name, double value) {
primiano9f75b242015-06-11 21:15:07 +0900101 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
102 pickle_.WriteBytes(&kTypeDouble, 1);
103 pickle_.WriteDouble(value);
104 WriteKeyNameAsRawPtr(pickle_, name);
105}
106
jbroman5a1db872015-11-19 01:19:48 +0900107void TracedValue::SetDoubleWithCopiedName(base::StringPiece name,
primiano9f75b242015-06-11 21:15:07 +0900108 double value) {
109 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
110 pickle_.WriteBytes(&kTypeDouble, 1);
111 pickle_.WriteDouble(value);
jbroman5a1db872015-11-19 01:19:48 +0900112 WriteKeyNameWithCopy(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900113}
114
115void TracedValue::SetBoolean(const char* name, bool value) {
primiano9f75b242015-06-11 21:15:07 +0900116 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
117 pickle_.WriteBytes(&kTypeBool, 1);
118 pickle_.WriteBool(value);
119 WriteKeyNameAsRawPtr(pickle_, name);
120}
121
jbroman5a1db872015-11-19 01:19:48 +0900122void TracedValue::SetBooleanWithCopiedName(base::StringPiece name,
primiano9f75b242015-06-11 21:15:07 +0900123 bool value) {
124 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
125 pickle_.WriteBytes(&kTypeBool, 1);
126 pickle_.WriteBool(value);
jbroman5a1db872015-11-19 01:19:48 +0900127 WriteKeyNameWithCopy(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900128}
129
jbroman5a1db872015-11-19 01:19:48 +0900130void TracedValue::SetString(const char* name, base::StringPiece value) {
primiano9f75b242015-06-11 21:15:07 +0900131 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
132 pickle_.WriteBytes(&kTypeString, 1);
133 pickle_.WriteString(value);
134 WriteKeyNameAsRawPtr(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900135}
136
jbroman5a1db872015-11-19 01:19:48 +0900137void TracedValue::SetStringWithCopiedName(base::StringPiece name,
138 base::StringPiece value) {
primiano9f75b242015-06-11 21:15:07 +0900139 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
140 pickle_.WriteBytes(&kTypeString, 1);
141 pickle_.WriteString(value);
jbroman5a1db872015-11-19 01:19:48 +0900142 WriteKeyNameWithCopy(pickle_, name);
primiano9f75b242015-06-11 21:15:07 +0900143}
144
145void TracedValue::SetValue(const char* name, const TracedValue& value) {
146 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
147 BeginDictionary(name);
148 pickle_.WriteBytes(value.pickle_.payload(),
149 static_cast<int>(value.pickle_.payload_size()));
150 EndDictionary();
151}
152
jbroman5a1db872015-11-19 01:19:48 +0900153void TracedValue::SetValueWithCopiedName(base::StringPiece name,
primiano9f75b242015-06-11 21:15:07 +0900154 const TracedValue& value) {
155 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
156 BeginDictionaryWithCopiedName(name);
157 pickle_.WriteBytes(value.pickle_.payload(),
158 static_cast<int>(value.pickle_.payload_size()));
159 EndDictionary();
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900160}
161
162void TracedValue::BeginDictionary(const char* name) {
primiano9f75b242015-06-11 21:15:07 +0900163 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
164 DEBUG_PUSH_CONTAINER(kStackTypeDict);
165 pickle_.WriteBytes(&kTypeStartDict, 1);
166 WriteKeyNameAsRawPtr(pickle_, name);
167}
168
jbroman5a1db872015-11-19 01:19:48 +0900169void TracedValue::BeginDictionaryWithCopiedName(base::StringPiece name) {
primiano9f75b242015-06-11 21:15:07 +0900170 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
171 DEBUG_PUSH_CONTAINER(kStackTypeDict);
172 pickle_.WriteBytes(&kTypeStartDict, 1);
jbroman5a1db872015-11-19 01:19:48 +0900173 WriteKeyNameWithCopy(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900174}
175
176void TracedValue::BeginArray(const char* name) {
primiano9f75b242015-06-11 21:15:07 +0900177 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
178 DEBUG_PUSH_CONTAINER(kStackTypeArray);
179 pickle_.WriteBytes(&kTypeStartArray, 1);
180 WriteKeyNameAsRawPtr(pickle_, name);
181}
182
jbroman5a1db872015-11-19 01:19:48 +0900183void TracedValue::BeginArrayWithCopiedName(base::StringPiece name) {
primiano9f75b242015-06-11 21:15:07 +0900184 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
185 DEBUG_PUSH_CONTAINER(kStackTypeArray);
186 pickle_.WriteBytes(&kTypeStartArray, 1);
jbroman5a1db872015-11-19 01:19:48 +0900187 WriteKeyNameWithCopy(pickle_, name);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900188}
189
190void TracedValue::EndDictionary() {
primiano9f75b242015-06-11 21:15:07 +0900191 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
192 DEBUG_POP_CONTAINER();
193 pickle_.WriteBytes(&kTypeEndDict, 1);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900194}
195
196void TracedValue::AppendInteger(int value) {
primiano9f75b242015-06-11 21:15:07 +0900197 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
198 pickle_.WriteBytes(&kTypeInt, 1);
199 pickle_.WriteInt(value);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900200}
201
202void TracedValue::AppendDouble(double value) {
primiano9f75b242015-06-11 21:15:07 +0900203 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
204 pickle_.WriteBytes(&kTypeDouble, 1);
205 pickle_.WriteDouble(value);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900206}
207
208void TracedValue::AppendBoolean(bool value) {
primiano9f75b242015-06-11 21:15:07 +0900209 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
210 pickle_.WriteBytes(&kTypeBool, 1);
211 pickle_.WriteBool(value);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900212}
213
jbroman5a1db872015-11-19 01:19:48 +0900214void TracedValue::AppendString(base::StringPiece value) {
primiano9f75b242015-06-11 21:15:07 +0900215 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
216 pickle_.WriteBytes(&kTypeString, 1);
217 pickle_.WriteString(value);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900218}
219
220void TracedValue::BeginArray() {
primiano9f75b242015-06-11 21:15:07 +0900221 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
222 DEBUG_PUSH_CONTAINER(kStackTypeArray);
223 pickle_.WriteBytes(&kTypeStartArray, 1);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900224}
225
226void TracedValue::BeginDictionary() {
primiano9f75b242015-06-11 21:15:07 +0900227 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
228 DEBUG_PUSH_CONTAINER(kStackTypeDict);
229 pickle_.WriteBytes(&kTypeStartDict, 1);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900230}
231
232void TracedValue::EndArray() {
primiano9f75b242015-06-11 21:15:07 +0900233 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
234 DEBUG_POP_CONTAINER();
235 pickle_.WriteBytes(&kTypeEndArray, 1);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900236}
237
dchengcc8e4d82016-04-05 06:25:51 +0900238void TracedValue::SetValue(const char* name,
239 std::unique_ptr<base::Value> value) {
primiano9f75b242015-06-11 21:15:07 +0900240 SetBaseValueWithCopiedName(name, *value);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900241}
242
jbroman5a1db872015-11-19 01:19:48 +0900243void TracedValue::SetBaseValueWithCopiedName(base::StringPiece name,
primiano9f75b242015-06-11 21:15:07 +0900244 const base::Value& value) {
245 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
246 switch (value.GetType()) {
jdoerrie89ee31a2016-12-08 00:43:28 +0900247 case base::Value::Type::NONE:
248 case base::Value::Type::BINARY:
primiano9f75b242015-06-11 21:15:07 +0900249 NOTREACHED();
250 break;
251
jdoerrie89ee31a2016-12-08 00:43:28 +0900252 case base::Value::Type::BOOLEAN: {
primiano9f75b242015-06-11 21:15:07 +0900253 bool bool_value;
254 value.GetAsBoolean(&bool_value);
255 SetBooleanWithCopiedName(name, bool_value);
256 } break;
257
jdoerrie89ee31a2016-12-08 00:43:28 +0900258 case base::Value::Type::INTEGER: {
primiano9f75b242015-06-11 21:15:07 +0900259 int int_value;
260 value.GetAsInteger(&int_value);
261 SetIntegerWithCopiedName(name, int_value);
262 } break;
263
jdoerrie89ee31a2016-12-08 00:43:28 +0900264 case base::Value::Type::DOUBLE: {
primiano9f75b242015-06-11 21:15:07 +0900265 double double_value;
266 value.GetAsDouble(&double_value);
267 SetDoubleWithCopiedName(name, double_value);
268 } break;
269
jdoerrie89ee31a2016-12-08 00:43:28 +0900270 case base::Value::Type::STRING: {
jdoerrie0d1295b2017-03-06 20:12:04 +0900271 const Value* string_value;
primiano9f75b242015-06-11 21:15:07 +0900272 value.GetAsString(&string_value);
273 SetStringWithCopiedName(name, string_value->GetString());
274 } break;
275
jdoerrie89ee31a2016-12-08 00:43:28 +0900276 case base::Value::Type::DICTIONARY: {
primiano9f75b242015-06-11 21:15:07 +0900277 const DictionaryValue* dict_value;
278 value.GetAsDictionary(&dict_value);
279 BeginDictionaryWithCopiedName(name);
280 for (DictionaryValue::Iterator it(*dict_value); !it.IsAtEnd();
281 it.Advance()) {
282 SetBaseValueWithCopiedName(it.key(), it.value());
283 }
284 EndDictionary();
285 } break;
286
jdoerrie89ee31a2016-12-08 00:43:28 +0900287 case base::Value::Type::LIST: {
primiano9f75b242015-06-11 21:15:07 +0900288 const ListValue* list_value;
289 value.GetAsList(&list_value);
290 BeginArrayWithCopiedName(name);
dcheng1fa44fb2016-05-26 03:30:47 +0900291 for (const auto& base_value : *list_value)
jdoerrie45184002017-04-12 03:09:14 +0900292 AppendBaseValue(base_value);
primiano9f75b242015-06-11 21:15:07 +0900293 EndArray();
294 } break;
295 }
296}
297
298void TracedValue::AppendBaseValue(const base::Value& value) {
299 DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray);
300 switch (value.GetType()) {
jdoerrie89ee31a2016-12-08 00:43:28 +0900301 case base::Value::Type::NONE:
302 case base::Value::Type::BINARY:
primiano9f75b242015-06-11 21:15:07 +0900303 NOTREACHED();
304 break;
305
jdoerrie89ee31a2016-12-08 00:43:28 +0900306 case base::Value::Type::BOOLEAN: {
primiano9f75b242015-06-11 21:15:07 +0900307 bool bool_value;
308 value.GetAsBoolean(&bool_value);
309 AppendBoolean(bool_value);
310 } break;
311
jdoerrie89ee31a2016-12-08 00:43:28 +0900312 case base::Value::Type::INTEGER: {
primiano9f75b242015-06-11 21:15:07 +0900313 int int_value;
314 value.GetAsInteger(&int_value);
315 AppendInteger(int_value);
316 } break;
317
jdoerrie89ee31a2016-12-08 00:43:28 +0900318 case base::Value::Type::DOUBLE: {
primiano9f75b242015-06-11 21:15:07 +0900319 double double_value;
320 value.GetAsDouble(&double_value);
321 AppendDouble(double_value);
322 } break;
323
jdoerrie89ee31a2016-12-08 00:43:28 +0900324 case base::Value::Type::STRING: {
jdoerrie0d1295b2017-03-06 20:12:04 +0900325 const Value* string_value;
primiano9f75b242015-06-11 21:15:07 +0900326 value.GetAsString(&string_value);
327 AppendString(string_value->GetString());
328 } break;
329
jdoerrie89ee31a2016-12-08 00:43:28 +0900330 case base::Value::Type::DICTIONARY: {
primiano9f75b242015-06-11 21:15:07 +0900331 const DictionaryValue* dict_value;
332 value.GetAsDictionary(&dict_value);
333 BeginDictionary();
334 for (DictionaryValue::Iterator it(*dict_value); !it.IsAtEnd();
335 it.Advance()) {
336 SetBaseValueWithCopiedName(it.key(), it.value());
337 }
338 EndDictionary();
339 } break;
340
jdoerrie89ee31a2016-12-08 00:43:28 +0900341 case base::Value::Type::LIST: {
primiano9f75b242015-06-11 21:15:07 +0900342 const ListValue* list_value;
343 value.GetAsList(&list_value);
344 BeginArray();
dcheng1fa44fb2016-05-26 03:30:47 +0900345 for (const auto& base_value : *list_value)
jdoerrie45184002017-04-12 03:09:14 +0900346 AppendBaseValue(base_value);
primiano9f75b242015-06-11 21:15:07 +0900347 EndArray();
348 } break;
349 }
350}
351
dchengcc8e4d82016-04-05 06:25:51 +0900352std::unique_ptr<base::Value> TracedValue::ToBaseValue() const {
353 std::unique_ptr<DictionaryValue> root(new DictionaryValue);
primiano9f75b242015-06-11 21:15:07 +0900354 DictionaryValue* cur_dict = root.get();
355 ListValue* cur_list = nullptr;
356 std::vector<Value*> stack;
357 PickleIterator it(pickle_);
358 const char* type;
359
360 while (it.ReadBytes(&type, 1)) {
361 DCHECK((cur_dict && !cur_list) || (cur_list && !cur_dict));
362 switch (*type) {
363 case kTypeStartDict: {
vmpstr39d09dc2016-06-29 11:15:58 +0900364 auto* new_dict = new DictionaryValue();
primiano9f75b242015-06-11 21:15:07 +0900365 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900366 cur_dict->SetWithoutPathExpansion(ReadKeyName(it),
dchengcc8e4d82016-04-05 06:25:51 +0900367 WrapUnique(new_dict));
primiano9f75b242015-06-11 21:15:07 +0900368 stack.push_back(cur_dict);
369 cur_dict = new_dict;
370 } else {
dchengcc8e4d82016-04-05 06:25:51 +0900371 cur_list->Append(WrapUnique(new_dict));
jdoerrie45184002017-04-12 03:09:14 +0900372 // |new_dict| is invalidated at this point, so |cur_dict| needs to be
373 // reset.
374 cur_list->GetDictionary(cur_list->GetSize() - 1, &cur_dict);
primiano9f75b242015-06-11 21:15:07 +0900375 stack.push_back(cur_list);
376 cur_list = nullptr;
primiano9f75b242015-06-11 21:15:07 +0900377 }
378 } break;
379
380 case kTypeEndArray:
381 case kTypeEndDict: {
382 if (stack.back()->GetAsDictionary(&cur_dict)) {
383 cur_list = nullptr;
384 } else if (stack.back()->GetAsList(&cur_list)) {
385 cur_dict = nullptr;
386 }
387 stack.pop_back();
388 } break;
389
390 case kTypeStartArray: {
vmpstr39d09dc2016-06-29 11:15:58 +0900391 auto* new_list = new ListValue();
primiano9f75b242015-06-11 21:15:07 +0900392 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900393 cur_dict->SetWithoutPathExpansion(ReadKeyName(it),
dchengcc8e4d82016-04-05 06:25:51 +0900394 WrapUnique(new_list));
primiano9f75b242015-06-11 21:15:07 +0900395 stack.push_back(cur_dict);
396 cur_dict = nullptr;
397 cur_list = new_list;
398 } else {
dchengcc8e4d82016-04-05 06:25:51 +0900399 cur_list->Append(WrapUnique(new_list));
primiano9f75b242015-06-11 21:15:07 +0900400 stack.push_back(cur_list);
jdoerrie45184002017-04-12 03:09:14 +0900401 // |cur_list| is invalidated at this point, so it needs to be reset.
402 cur_list->GetList(cur_list->GetSize() - 1, &cur_list);
primiano9f75b242015-06-11 21:15:07 +0900403 }
404 } break;
405
406 case kTypeBool: {
407 bool value;
408 CHECK(it.ReadBool(&value));
409 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900410 cur_dict->SetBooleanWithoutPathExpansion(ReadKeyName(it), value);
primiano9f75b242015-06-11 21:15:07 +0900411 } else {
412 cur_list->AppendBoolean(value);
413 }
414 } break;
415
416 case kTypeInt: {
417 int value;
418 CHECK(it.ReadInt(&value));
419 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900420 cur_dict->SetIntegerWithoutPathExpansion(ReadKeyName(it), value);
primiano9f75b242015-06-11 21:15:07 +0900421 } else {
422 cur_list->AppendInteger(value);
423 }
424 } break;
425
426 case kTypeDouble: {
427 double value;
428 CHECK(it.ReadDouble(&value));
429 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900430 cur_dict->SetDoubleWithoutPathExpansion(ReadKeyName(it), value);
primiano9f75b242015-06-11 21:15:07 +0900431 } else {
432 cur_list->AppendDouble(value);
433 }
434 } break;
435
436 case kTypeString: {
437 std::string value;
438 CHECK(it.ReadString(&value));
439 if (cur_dict) {
primianoe62a75d2015-09-18 18:57:40 +0900440 cur_dict->SetStringWithoutPathExpansion(ReadKeyName(it), value);
primiano9f75b242015-06-11 21:15:07 +0900441 } else {
442 cur_list->AppendString(value);
443 }
444 } break;
445
446 default:
447 NOTREACHED();
448 }
449 }
450 DCHECK(stack.empty());
danakj800d2ea2015-11-25 14:29:58 +0900451 return std::move(root);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900452}
453
454void TracedValue::AppendAsTraceFormat(std::string* out) const {
primiano9f75b242015-06-11 21:15:07 +0900455 DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict);
456 DCHECK_CONTAINER_STACK_DEPTH_EQ(1u);
457
458 // TODO(primiano): this could be smarter, skip the ToBaseValue encoding and
459 // produce the JSON on its own. This will require refactoring JSONWriter
460 // to decouple the base::Value traversal from the JSON writing bits
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900461 std::string tmp;
primiano9f75b242015-06-11 21:15:07 +0900462 JSONWriter::Write(*ToBaseValue(), &tmp);
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900463 *out += tmp;
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900464}
465
primianof5999252015-06-11 09:43:15 +0900466void TracedValue::EstimateTraceMemoryOverhead(
467 TraceEventMemoryOverhead* overhead) {
primianofb2bebf2015-06-13 05:38:20 +0900468 overhead->Add("TracedValue",
primiano47c69062015-07-25 05:13:32 +0900469 /* allocated size */
bashi6cd20122016-04-12 10:05:43 +0900470 pickle_.GetTotalAllocatedSize(),
primiano47c69062015-07-25 05:13:32 +0900471 /* resident size */
bashi6cd20122016-04-12 10:05:43 +0900472 pickle_.size());
primianof5999252015-06-11 09:43:15 +0900473}
474
primianod6acdd22015-02-05 23:20:26 +0900475} // namespace trace_event
yurys@chromium.org937ea9d2014-08-01 22:10:38 +0900476} // namespace base