Results.cpp revision 9de4dec874148d30cc1d4c498d38cd048a8164ca
1//===-- Results.cpp ---------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "Results.h" 11#include <assert.h> 12 13#ifdef __APPLE__ 14#include "CFCMutableArray.h" 15#include "CFCMutableDictionary.h" 16#include "CFCReleaser.h" 17#include "CFCString.h" 18#endif 19 20using namespace lldb_perf; 21 22static void 23AddResultToArray (CFCMutableArray &array, Results::Result *result); 24 25static void 26AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result); 27 28static void 29AddResultToArray (CFCMutableArray &parent_array, Results::Result *result) 30{ 31 switch (result->GetType()) 32 { 33 case Results::Result::Type::Invalid: 34 break; 35 36 case Results::Result::Type::Array: 37 { 38 Results::Array *value = result->GetAsArray(); 39 CFCMutableArray array; 40 value->ForEach([&array](const Results::ResultSP &value_sp) -> bool 41 { 42 AddResultToArray (array, value_sp.get()); 43 return true; 44 }); 45 parent_array.AppendValue(array.get(), true); 46 } 47 break; 48 49 case Results::Result::Type::Dictionary: 50 { 51 Results::Dictionary *value = result->GetAsDictionary(); 52 CFCMutableDictionary dict; 53 value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool 54 { 55 AddResultToDictionary (dict, key.c_str(), value_sp.get()); 56 return true; 57 }); 58 if (result->GetDescription()) 59 { 60 dict.AddValueCString(CFSTR("description"), result->GetDescription()); 61 } 62 parent_array.AppendValue(dict.get(), true); 63 } 64 break; 65 66 case Results::Result::Type::Double: 67 { 68 double d = result->GetAsDouble()->GetValue(); 69 CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &d)); 70 if (cf_number.get()) 71 parent_array.AppendValue(cf_number.get(), true); 72 } 73 break; 74 case Results::Result::Type::String: 75 { 76 CFCString cfstr (result->GetAsString()->GetValue()); 77 if (cfstr.get()) 78 parent_array.AppendValue(cfstr.get(), true); 79 } 80 break; 81 82 case Results::Result::Type::Unsigned: 83 { 84 uint64_t uval64 = result->GetAsUnsigned()->GetValue(); 85 CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &uval64)); 86 if (cf_number.get()) 87 parent_array.AppendValue(cf_number.get(), true); 88 } 89 break; 90 91 default: 92 assert (!"unhandled result"); 93 break; 94 } 95} 96 97 98static void 99AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result) 100{ 101 assert (key && key[0]); 102 CFCString cf_key(key); 103 switch (result->GetType()) 104 { 105 case Results::Result::Type::Invalid: 106 break; 107 108 case Results::Result::Type::Array: 109 { 110 Results::Array *value = result->GetAsArray(); 111 CFCMutableArray array; 112 value->ForEach([&array](const Results::ResultSP &value_sp) -> bool 113 { 114 AddResultToArray (array, value_sp.get()); 115 return true; 116 }); 117 parent_dict.AddValue(cf_key.get(), array.get(), true); 118 } 119 break; 120 case Results::Result::Type::Dictionary: 121 { 122 Results::Dictionary *value = result->GetAsDictionary(); 123 CFCMutableDictionary dict; 124 value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool 125 { 126 AddResultToDictionary (dict, key.c_str(), value_sp.get()); 127 return true; 128 }); 129 if (result->GetDescription()) 130 { 131 dict.AddValueCString(CFSTR("description"), result->GetDescription()); 132 } 133 parent_dict.AddValue(cf_key.get(), dict.get(), true); 134 } 135 break; 136 case Results::Result::Type::Double: 137 { 138 parent_dict.SetValueDouble(cf_key.get(), result->GetAsDouble()->GetValue(), true); 139 } 140 break; 141 case Results::Result::Type::String: 142 { 143 parent_dict.SetValueCString(cf_key.get(), result->GetAsString()->GetValue(), true); 144 } 145 break; 146 147 case Results::Result::Type::Unsigned: 148 { 149 parent_dict.SetValueUInt64 (cf_key.get(), result->GetAsUnsigned()->GetValue(), true); 150 } 151 break; 152 default: 153 assert (!"unhandled result"); 154 break; 155 } 156} 157void 158Results::Write (const char *out_path) 159{ 160#ifdef __APPLE__ 161 CFCMutableDictionary dict; 162 163 m_results.ForEach([&dict](const std::string &key, const ResultSP &value_sp) -> bool 164 { 165 AddResultToDictionary (dict, key.c_str(), value_sp.get()); 166 return true; 167 }); 168 CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, dict.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL); 169 170 CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)out_path, strlen(out_path), FALSE); 171 172 CFURLWriteDataAndPropertiesToResource(file, xmlData, NULL, NULL); 173#endif 174} 175 176void 177Results::Dictionary::AddUnsigned (const char *name, const char *description, uint64_t value) 178{ 179 assert (name && name[0]); 180 if (description && description[0]) 181 { 182 std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ()); 183 value_dict_ap->AddString("description", NULL, description); 184 value_dict_ap->AddUnsigned("value", NULL, value); 185 m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release()); 186 } 187 else 188 m_dictionary[std::string(name)] = ResultSP (new Unsigned (name, description, value)); 189} 190 191void 192Results::Dictionary::AddDouble (const char *name, const char *description, double value) 193{ 194 assert (name && name[0]); 195 196 if (description && description[0]) 197 { 198 std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ()); 199 value_dict_ap->AddString("description", NULL, description); 200 value_dict_ap->AddDouble("value", NULL, value); 201 m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release()); 202 } 203 else 204 m_dictionary[std::string(name)] = ResultSP (new Double (name, description, value)); 205} 206void 207Results::Dictionary::AddString (const char *name, const char *description, const char *value) 208{ 209 assert (name && name[0]); 210 if (description && description[0]) 211 { 212 std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ()); 213 value_dict_ap->AddString("description", NULL, description); 214 value_dict_ap->AddString("value", NULL, value); 215 m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release()); 216 } 217 else 218 m_dictionary[std::string(name)] = ResultSP (new String (name, description, value)); 219} 220 221void 222Results::Dictionary::Add (const char *name, const char *description, const ResultSP &result_sp) 223{ 224 assert (name && name[0]); 225 if (description && description[0]) 226 { 227 std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ()); 228 value_dict_ap->AddString("description", NULL, description); 229 value_dict_ap->Add("value", NULL, result_sp); 230 m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release()); 231 } 232 else 233 m_dictionary[std::string(name)] = result_sp; 234} 235 236void 237Results::Dictionary::ForEach (const std::function <bool (const std::string &, const ResultSP &)> &callback) 238{ 239 collection::const_iterator pos, end = m_dictionary.end(); 240 for (pos = m_dictionary.begin(); pos != end; ++pos) 241 { 242 if (callback (pos->first.c_str(), pos->second) == false) 243 return; 244 } 245} 246 247 248 249void 250Results::Array::Append (const ResultSP &result_sp) 251{ 252 m_array.push_back (result_sp); 253} 254 255void 256Results::Array::ForEach (const std::function <bool (const ResultSP &)> &callback) 257{ 258 collection::const_iterator pos, end = m_array.end(); 259 for (pos = m_array.begin(); pos != end; ++pos) 260 { 261 if (callback (*pos) == false) 262 return; 263 } 264} 265 266 267 268