blob: de86f6b7d3864d7de0bcc5a92c5922e8be96c380 [file] [log] [blame]
Greg Clayton880afc52013-03-22 02:31:35 +00001//===-- 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