diff options
Diffstat (limited to 'tools/lldb-perf/lib/Results.cpp')
-rw-r--r-- | tools/lldb-perf/lib/Results.cpp | 275 |
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; + } +} + + + |