aboutsummaryrefslogtreecommitdiff
path: root/tools/lldb-perf/lib/Results.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-perf/lib/Results.cpp')
-rw-r--r--tools/lldb-perf/lib/Results.cpp275
1 files changed, 275 insertions, 0 deletions
diff --git a/tools/lldb-perf/lib/Results.cpp b/tools/lldb-perf/lib/Results.cpp
new file mode 100644
index 000000000000..6abf67e53b67
--- /dev/null
+++ b/tools/lldb-perf/lib/Results.cpp
@@ -0,0 +1,275 @@
+//===-- Results.cpp ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Results.h"
+#include <assert.h>
+
+#ifdef __APPLE__
+#include "CFCMutableArray.h"
+#include "CFCMutableDictionary.h"
+#include "CFCReleaser.h"
+#include "CFCString.h"
+#endif
+
+using namespace lldb_perf;
+
+static void
+AddResultToArray (CFCMutableArray &array, Results::Result *result);
+
+static void
+AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result);
+
+static void
+AddResultToArray (CFCMutableArray &parent_array, Results::Result *result)
+{
+ switch (result->GetType())
+ {
+ case Results::Result::Type::Invalid:
+ break;
+
+ case Results::Result::Type::Array:
+ {
+ Results::Array *value = result->GetAsArray();
+ CFCMutableArray array;
+ value->ForEach([&array](const Results::ResultSP &value_sp) -> bool
+ {
+ AddResultToArray (array, value_sp.get());
+ return true;
+ });
+ parent_array.AppendValue(array.get(), true);
+ }
+ break;
+
+ case Results::Result::Type::Dictionary:
+ {
+ Results::Dictionary *value = result->GetAsDictionary();
+ CFCMutableDictionary dict;
+ value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool
+ {
+ AddResultToDictionary (dict, key.c_str(), value_sp.get());
+ return true;
+ });
+ if (result->GetDescription())
+ {
+ dict.AddValueCString(CFSTR("description"), result->GetDescription());
+ }
+ parent_array.AppendValue(dict.get(), true);
+ }
+ break;
+
+ case Results::Result::Type::Double:
+ {
+ double d = result->GetAsDouble()->GetValue();
+ CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &d));
+ if (cf_number.get())
+ parent_array.AppendValue(cf_number.get(), true);
+ }
+ break;
+ case Results::Result::Type::String:
+ {
+ CFCString cfstr (result->GetAsString()->GetValue());
+ if (cfstr.get())
+ parent_array.AppendValue(cfstr.get(), true);
+ }
+ break;
+
+ case Results::Result::Type::Unsigned:
+ {
+ uint64_t uval64 = result->GetAsUnsigned()->GetValue();
+ CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &uval64));
+ if (cf_number.get())
+ parent_array.AppendValue(cf_number.get(), true);
+ }
+ break;
+
+ default:
+ assert (!"unhandled result");
+ break;
+ }
+}
+
+
+static void
+AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result)
+{
+ assert (key && key[0]);
+ CFCString cf_key(key);
+ switch (result->GetType())
+ {
+ case Results::Result::Type::Invalid:
+ break;
+
+ case Results::Result::Type::Array:
+ {
+ Results::Array *value = result->GetAsArray();
+ CFCMutableArray array;
+ value->ForEach([&array](const Results::ResultSP &value_sp) -> bool
+ {
+ AddResultToArray (array, value_sp.get());
+ return true;
+ });
+ parent_dict.AddValue(cf_key.get(), array.get(), true);
+ }
+ break;
+ case Results::Result::Type::Dictionary:
+ {
+ Results::Dictionary *value = result->GetAsDictionary();
+ CFCMutableDictionary dict;
+ value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool
+ {
+ AddResultToDictionary (dict, key.c_str(), value_sp.get());
+ return true;
+ });
+ if (result->GetDescription())
+ {
+ dict.AddValueCString(CFSTR("description"), result->GetDescription());
+ }
+ parent_dict.AddValue(cf_key.get(), dict.get(), true);
+ }
+ break;
+ case Results::Result::Type::Double:
+ {
+ parent_dict.SetValueDouble(cf_key.get(), result->GetAsDouble()->GetValue(), true);
+ }
+ break;
+ case Results::Result::Type::String:
+ {
+ parent_dict.SetValueCString(cf_key.get(), result->GetAsString()->GetValue(), true);
+ }
+ break;
+
+ case Results::Result::Type::Unsigned:
+ {
+ parent_dict.SetValueUInt64 (cf_key.get(), result->GetAsUnsigned()->GetValue(), true);
+ }
+ break;
+ default:
+ assert (!"unhandled result");
+ break;
+ }
+}
+void
+Results::Write (const char *out_path)
+{
+#ifdef __APPLE__
+ CFCMutableDictionary dict;
+
+ m_results.ForEach([&dict](const std::string &key, const ResultSP &value_sp) -> bool
+ {
+ AddResultToDictionary (dict, key.c_str(), value_sp.get());
+ return true;
+ });
+ CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, dict.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
+
+ if (out_path == NULL)
+ out_path = "/dev/stdout";
+
+ CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)out_path, strlen(out_path), FALSE);
+
+ CFURLWriteDataAndPropertiesToResource(file, xmlData, NULL, NULL);
+#endif
+}
+
+Results::ResultSP
+Results::Dictionary::AddUnsigned (const char *name, const char *description, uint64_t value)
+{
+ assert (name && name[0]);
+ if (description && description[0])
+ {
+ std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
+ value_dict_ap->AddString("description", NULL, description);
+ value_dict_ap->AddUnsigned("value", NULL, value);
+ m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
+ }
+ else
+ m_dictionary[std::string(name)] = ResultSP (new Unsigned (name, description, value));
+ return m_dictionary[std::string(name)];
+}
+
+Results::ResultSP
+Results::Dictionary::AddDouble (const char *name, const char *description, double value)
+{
+ assert (name && name[0]);
+
+ if (description && description[0])
+ {
+ std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
+ value_dict_ap->AddString("description", NULL, description);
+ value_dict_ap->AddDouble("value", NULL, value);
+ m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
+ }
+ else
+ m_dictionary[std::string(name)] = ResultSP (new Double (name, description, value));
+ return m_dictionary[std::string(name)];
+}
+Results::ResultSP
+Results::Dictionary::AddString (const char *name, const char *description, const char *value)
+{
+ assert (name && name[0]);
+ if (description && description[0])
+ {
+ std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
+ value_dict_ap->AddString("description", NULL, description);
+ value_dict_ap->AddString("value", NULL, value);
+ m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
+ }
+ else
+ m_dictionary[std::string(name)] = ResultSP (new String (name, description, value));
+ return m_dictionary[std::string(name)];
+}
+
+Results::ResultSP
+Results::Dictionary::Add (const char *name, const char *description, const ResultSP &result_sp)
+{
+ assert (name && name[0]);
+ if (description && description[0])
+ {
+ std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
+ value_dict_ap->AddString("description", NULL, description);
+ value_dict_ap->Add("value", NULL, result_sp);
+ m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
+ }
+ else
+ m_dictionary[std::string(name)] = result_sp;
+ return m_dictionary[std::string(name)];
+}
+
+void
+Results::Dictionary::ForEach (const std::function <bool (const std::string &, const ResultSP &)> &callback)
+{
+ collection::const_iterator pos, end = m_dictionary.end();
+ for (pos = m_dictionary.begin(); pos != end; ++pos)
+ {
+ if (callback (pos->first.c_str(), pos->second) == false)
+ return;
+ }
+}
+
+
+
+Results::ResultSP
+Results::Array::Append (const ResultSP &result_sp)
+{
+ m_array.push_back (result_sp);
+ return result_sp;
+}
+
+void
+Results::Array::ForEach (const std::function <bool (const ResultSP &)> &callback)
+{
+ collection::const_iterator pos, end = m_array.end();
+ for (pos = m_array.begin(); pos != end; ++pos)
+ {
+ if (callback (*pos) == false)
+ return;
+ }
+}
+
+
+