Index: base/debug/trace_event.cc |
diff --git a/base/debug/trace_event.cc b/base/debug/trace_event.cc |
index 879f3a978f9361900a8658b61c4ead4ef5f75f0b..3f321018417d5a9027d003c046418adf77547678 100644 |
--- a/base/debug/trace_event.cc |
+++ b/base/debug/trace_event.cc |
@@ -5,18 +5,22 @@ |
#include "base/debug/trace_event.h" |
#include <algorithm> |
+#include <math.h> |
#if defined(OS_WIN) |
#include "base/debug/trace_event_win.h" |
#endif |
#include "base/format_macros.h" |
+#include "base/json/json_reader.h" |
#include "base/memory/ref_counted_memory.h" |
+#include "base/memory/scoped_ptr.h" |
#include "base/process_util.h" |
#include "base/stringprintf.h" |
#include "base/threading/thread_local.h" |
#include "base/utf_string_conversions.h" |
#include "base/stl_util.h" |
#include "base/time.h" |
+#include "base/values.h" |
#define USE_UNRELIABLE_NOW |
@@ -126,6 +130,21 @@ const char* GetPhaseStr(TraceEventPhase phase) { |
} |
} |
+TraceEventPhase GetPhaseFromStr(const char* phase) { |
+ switch(*phase) { |
+ case 'B': |
+ return TRACE_EVENT_PHASE_BEGIN; |
+ case 'I': |
+ return TRACE_EVENT_PHASE_INSTANT; |
+ case 'E': |
+ return TRACE_EVENT_PHASE_END; |
+ case 'M': |
+ return TRACE_EVENT_PHASE_METADATA; |
+ default: |
+ return TRACE_EVENT_PHASE_BEGIN; |
+ } |
+} |
+ |
size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } |
// Copies |*member| into |*buffer|, sets |*member| to point to this new |
@@ -143,6 +162,112 @@ void CopyTraceEventParameter(char** buffer, |
} // namespace |
+TestTraceEvent::TestTraceEvent() |
+ : pid_tid(0, 0), |
+ timestamp(0), |
+ phase(TRACE_EVENT_PHASE_BEGIN), |
+ other_event(NULL) { |
+} |
+ |
+TestTraceEvent::TestTraceEvent(const base::Value* event_value) |
+ : pid_tid(0, 0), |
+ timestamp(0), |
+ phase(TRACE_EVENT_PHASE_BEGIN), |
+ other_event(NULL) { |
+ if (event_value->GetType() != base::Value::TYPE_DICTIONARY) |
+ return; |
+ const base::DictionaryValue* dictionary = |
+ static_cast<const base::DictionaryValue*>(event_value); |
+ |
+ std::string phase_str; |
+ base::DictionaryValue* args = NULL; |
+ |
+ if (dictionary->GetInteger("pid", &pid_tid.pid) && |
+ dictionary->GetInteger("tid", &pid_tid.tid) && |
+ dictionary->GetDouble("ts", ×tamp) && |
+ dictionary->GetString("cat", &category) && |
+ dictionary->GetString("name", &name) && |
+ dictionary->GetString("ph", &phase_str) && |
+ dictionary->GetDictionary("args", &args)) { |
+ |
+ phase = GetPhaseFromStr(phase_str.c_str()); |
+ |
+ // For each argument, copy the type and create a TraceValue. |
+ base::DictionaryValue::key_iterator keyi = args->begin_keys(); |
+ for (; keyi != args->end_keys(); ++keyi) { |
+ std::string str; |
+ bool boolean = false; |
+ int int_num = 0; |
+ double double_num = 0.0; |
+ Value* value = NULL; |
+ if (args->GetWithoutPathExpansion(*keyi, &value)) { |
+ if (value->GetAsString(&str)) |
+ arg_strings[*keyi] = str; |
+ else if (value->GetAsInteger(&int_num)) |
+ arg_numbers[*keyi] = static_cast<double>(int_num); |
+ else if (value->GetAsBoolean(&boolean)) |
+ arg_numbers[*keyi] = static_cast<double>(boolean ? 1 : 0); |
+ else if (value->GetAsDouble(&double_num)) |
+ arg_numbers[*keyi] = double_num; |
+ } |
+ } |
+ } |
+} |
+ |
+TestTraceEvent::~TestTraceEvent() { |
+} |
+ |
+bool TestTraceEvent::ParseEventsFromJson(const std::string& json, |
+ std::vector<TestTraceEvent>* output) { |
+ scoped_ptr<base::Value> root; |
+ root.reset(base::JSONReader::Read(json, false)); |
+ |
+ ListValue* root_list = NULL; |
+ if (!root.get() || !root->GetAsList(&root_list)) |
+ return false; |
+ |
+ for (size_t i = 0; i < root_list->GetSize(); ++i) { |
+ Value* item = NULL; |
+ if (root_list->Get(i, &item)) |
+ output->push_back(TestTraceEvent(item)); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool TestTraceEvent::GetDuration(double* duration) const { |
+ if (!other_event) |
+ return false; |
+ |
+ *duration = fabs(other_event->timestamp - timestamp); |
+ return true; |
+} |
+ |
+bool TestTraceEvent::IsArg(const std::string& name) const { |
+ return arg_numbers.find(name) != arg_numbers.end() || |
+ arg_strings.find(name) != arg_strings.end(); |
+} |
+ |
+bool TestTraceEvent::GetArgAsString(const std::string& name, |
+ std::string* arg) const { |
+ std::map<std::string, std::string>::const_iterator i = arg_strings.find(name); |
+ if (i != arg_strings.end()) { |
+ *arg = i->second; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool TestTraceEvent::GetArgAsNumber(const std::string& name, |
+ double* arg) const { |
+ std::map<std::string, double>::const_iterator i = arg_numbers.find(name); |
+ if (i != arg_numbers.end()) { |
+ *arg = i->second; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
TraceEvent::TraceEvent() |
: process_id_(0), |
thread_id_(0), |