| 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
|
|
|