Index: src/tracing/traced-value.cc |
diff --git a/src/tracing/traced-value.cc b/src/tracing/traced-value.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3406bbf6fe71bfbbb16e53471abda711eeeb99ec |
--- /dev/null |
+++ b/src/tracing/traced-value.cc |
@@ -0,0 +1,194 @@ |
+// Copyright 2016 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/tracing/traced-value.h" |
+ |
+#include "src/base/platform/platform.h" |
+ |
+namespace v8 { |
+namespace tracing { |
+ |
+namespace { |
+ |
+#define DCHECK_CURRENT_CONTAINER_IS(x) DCHECK_EQ(x, nesting_stack_.back()) |
+#define DCHECK_CONTAINER_STACK_DEPTH_EQ(x) DCHECK_EQ(x, nesting_stack_.size()) |
+#ifdef DEBUG |
+const bool kStackTypeDict = false; |
+const bool kStackTypeArray = true; |
+#define DEBUG_PUSH_CONTAINER(x) nesting_stack_.push_back(x) |
+#define DEBUG_POP_CONTAINER() nesting_stack_.pop_back() |
+#else |
+#define DEBUG_PUSH_CONTAINER(x) ((void)0) |
+#define DEBUG_POP_CONTAINER() ((void)0) |
+#endif |
+ |
+std::string EscapeString(const std::string& value) { |
+ std::string result; |
+ result.reserve(value.length() + 2); |
+ result += '"'; |
+ size_t length = value.length(); |
+ char number_buffer[10]; |
+ for (size_t src = 0; src < length; ++src) { |
+ char c = value[src]; |
+ switch (c) { |
+ case '\t': |
+ result += "\\t"; |
+ break; |
+ case '\n': |
+ result += "\\n"; |
+ break; |
+ case '\"': |
+ result += "\\\""; |
+ break; |
+ case '\\': |
+ result += "\\\\"; |
+ break; |
+ default: |
+ if (c < '\040') { |
+ base::OS::SNPrintF( |
+ number_buffer, arraysize(number_buffer), "\\u%04X", |
+ static_cast<unsigned>(static_cast<unsigned char>(c))); |
+ result += number_buffer; |
+ } else { |
+ result += c; |
+ } |
+ } |
+ } |
+ result += '"'; |
+ return result; |
+} |
+ |
+} // namespace |
+ |
+std::unique_ptr<TracedValue> TracedValue::Create() { |
+ return std::unique_ptr<TracedValue>(new TracedValue()); |
+} |
+ |
+TracedValue::TracedValue() : first_item_(true) { |
+ DEBUG_PUSH_CONTAINER(kStackTypeDict); |
+} |
+ |
+TracedValue::~TracedValue() { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ DEBUG_POP_CONTAINER(); |
+ DCHECK_CONTAINER_STACK_DEPTH_EQ(0u); |
+} |
+ |
+void TracedValue::SetInteger(const char* name, int value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ WriteName(name); |
+ data_ += std::to_string(value); |
+} |
+ |
+void TracedValue::SetDouble(const char* name, double value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ WriteName(name); |
+ data_ += std::to_string(value); |
+} |
+ |
+void TracedValue::SetBoolean(const char* name, bool value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ WriteName(name); |
+ data_ += value ? "true" : "false"; |
+} |
+ |
+void TracedValue::SetString(const char* name, const std::string& value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ WriteName(name); |
+ data_ += EscapeString(value); |
+} |
+ |
+void TracedValue::BeginDictionary(const char* name) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ DEBUG_PUSH_CONTAINER(kStackTypeDict); |
+ WriteName(name); |
+ data_ += '{'; |
+ first_item_ = true; |
+} |
+ |
+void TracedValue::BeginArray(const char* name) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ DEBUG_PUSH_CONTAINER(kStackTypeArray); |
+ WriteName(name); |
+ data_ += '['; |
+ first_item_ = true; |
+} |
+ |
+void TracedValue::AppendInteger(int value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ WriteComma(); |
+ data_ += std::to_string(value); |
+} |
+ |
+void TracedValue::AppendDouble(double value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ WriteComma(); |
+ data_ += std::to_string(value); |
+} |
+ |
+void TracedValue::AppendBoolean(bool value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ WriteComma(); |
+ data_ += value ? "true" : "false"; |
+} |
+ |
+void TracedValue::AppendString(const std::string& value) { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ WriteComma(); |
+ data_ += EscapeString(value); |
+} |
+ |
+void TracedValue::BeginDictionary() { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ DEBUG_PUSH_CONTAINER(kStackTypeDict); |
+ WriteComma(); |
+ data_ += '{'; |
+ first_item_ = true; |
+} |
+ |
+void TracedValue::BeginArray() { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ DEBUG_PUSH_CONTAINER(kStackTypeArray); |
+ WriteComma(); |
+ data_ += '['; |
+ first_item_ = true; |
+} |
+ |
+void TracedValue::EndDictionary() { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeDict); |
+ DEBUG_POP_CONTAINER(); |
+ data_ += '}'; |
+ first_item_ = false; |
+} |
+ |
+void TracedValue::EndArray() { |
+ DCHECK_CURRENT_CONTAINER_IS(kStackTypeArray); |
+ DEBUG_POP_CONTAINER(); |
+ data_ += ']'; |
+ first_item_ = false; |
+} |
+ |
+void TracedValue::WriteComma() { |
+ if (first_item_) { |
+ first_item_ = false; |
+ } else { |
+ data_ += ','; |
+ } |
+} |
+ |
+void TracedValue::WriteName(const char* name) { |
+ WriteComma(); |
+ data_ += '"'; |
+ data_ += name; |
+ data_ += "\":"; |
+} |
+ |
+void TracedValue::AppendAsTraceFormat(std::string* out) const { |
+ *out += '{'; |
+ *out += data_; |
+ *out += '}'; |
+} |
+ |
+} // namespace tracing |
+} // namespace v8 |