]> git.cworth.org Git - apitrace/blob - gui/apitracecall.cpp
Introduce ApiTrace which encapsulates the data.
[apitrace] / gui / apitracecall.cpp
1 #include "apitracecall.h"
2
3 #include "trace_model.hpp"
4
5 #include <QDebug>
6
7 ApiPointer::ApiPointer(int val)
8     : m_value(val)
9 {
10 }
11
12 QString ApiPointer::toString() const
13 {
14     if (m_value)
15         return QString("0x%1").arg(m_value, 0, 16);
16     else
17         return QLatin1String("NULL");
18 }
19
20 QString apiVariantToString(const QVariant &variant)
21 {
22     if (variant.userType() == QVariant::Double) {
23         return QString::number(variant.toFloat());
24     }
25
26     if (variant.userType() < QVariant::UserType) {
27         return variant.toString();
28     }
29
30     if (variant.canConvert<ApiPointer>()) {
31         return variant.value<ApiPointer>().toString();
32     }
33     if (variant.canConvert<ApiBitmask>()) {
34         return variant.value<ApiBitmask>().toString();
35     }
36     if (variant.canConvert<ApiStruct>()) {
37         return variant.value<ApiStruct>().toString();
38     }
39     if (variant.canConvert<ApiArray>()) {
40         return variant.value<ApiArray>().toString();
41     }
42
43     return QString();
44 }
45
46 ApiBitmask::ApiBitmask(const Trace::Bitmask *bitmask)
47     : m_value(0)
48 {
49     init(bitmask);
50 }
51
52
53 void ApiBitmask::init(const Trace::Bitmask *bitmask)
54 {
55     if (!bitmask)
56         return;
57
58     m_value = bitmask->value;
59     for (Trace::Bitmask::Signature::const_iterator it = bitmask->sig->begin();
60          it != bitmask->sig->end(); ++it) {
61         assert(it->second);
62         QPair<QString, unsigned long long> pair;
63
64         pair.first = QString::fromStdString(it->first);
65         pair.second = it->second;
66
67         m_sig.append(pair);
68     }
69 }
70
71 QString ApiBitmask::toString() const
72 {
73     QString str;
74     unsigned long long value = m_value;
75     bool first = true;
76     for (Signature::const_iterator it = m_sig.begin();
77          value != 0 && it != m_sig.end(); ++it) {
78         Q_ASSERT(it->second);
79         if ((value & it->second) == it->second) {
80             if (!first) {
81                 str += QLatin1String(" | ");
82             }
83             str += it->first;
84             value &= ~it->second;
85             first = false;
86         }
87     }
88     if (value || first) {
89         if (!first) {
90             str += QLatin1String(" | ");
91         }
92         str += QString::fromLatin1("0x%1").arg(value, 0, 16);
93     }
94     return str;
95 }
96
97 ApiStruct::ApiStruct(const Trace::Struct *s)
98 {
99     init(s);
100 }
101
102 QString ApiStruct::toString() const
103 {
104     QString str;
105
106     str += QLatin1String("{");
107     for (unsigned i = 0; i < m_members.count(); ++i) {
108         str += m_sig.memberNames[i];
109         str += QLatin1String(" = ");
110         str += apiVariantToString(m_members[i]);
111         if (i < m_members.count() - 1)
112             str += QLatin1String(", ");
113     }
114     str += QLatin1String("}");
115
116     return str;
117 }
118
119 void ApiStruct::init(const Trace::Struct *s)
120 {
121     if (!s)
122         return;
123
124     m_sig.name = QString::fromStdString(s->sig->name);
125     for (unsigned i = 0; i < s->members.size(); ++i) {
126         VariantVisitor vis;
127         m_sig.memberNames.append(
128             QString::fromStdString(s->sig->member_names[i]));
129         s->members[i]->visit(vis);
130         m_members.append(vis.variant());
131     }
132 }
133
134 void VariantVisitor::visit(Trace::Null *)
135 {
136     m_variant = QVariant(QLatin1String("NULL"));
137 }
138
139 void VariantVisitor::visit(Trace::Bool *node)
140 {
141     m_variant = QVariant(node->value);
142 }
143
144 void VariantVisitor::visit(Trace::SInt *node)
145 {
146     m_variant = QVariant(node->value);
147 }
148
149 void VariantVisitor::visit(Trace::UInt *node)
150 {
151     m_variant = QVariant(node->value);
152 }
153
154 void VariantVisitor::visit(Trace::Float *node)
155 {
156     m_variant = QVariant(node->value);
157 }
158
159 void VariantVisitor::visit(Trace::String *node)
160 {
161     m_variant = QVariant(QString::fromStdString(node->value));
162 }
163
164 void VariantVisitor::visit(Trace::Enum *e)
165 {
166     m_variant = QVariant(QString::fromStdString(e->sig->first));
167 }
168
169 void VariantVisitor::visit(Trace::Bitmask *bitmask)
170 {
171     m_variant = QVariant::fromValue(ApiBitmask(bitmask));
172 }
173
174 void VariantVisitor::visit(Trace::Struct *str)
175 {
176     m_variant = QVariant::fromValue(ApiStruct(str));
177 }
178
179 void VariantVisitor::visit(Trace::Array *array)
180 {
181     m_variant = QVariant::fromValue(ApiArray(array));
182 }
183
184 void VariantVisitor::visit(Trace::Blob *blob)
185 {
186     QByteArray barray = QByteArray::fromRawData(blob->buf, blob->size);
187     m_variant = QVariant(barray);
188 }
189
190 void VariantVisitor::visit(Trace::Pointer *ptr)
191 {
192     m_variant = QVariant::fromValue(ApiPointer(ptr->value));
193 }
194
195 ApiArray::ApiArray(const Trace::Array *arr)
196 {
197     init(arr);
198 }
199
200 QString ApiArray::toString() const
201 {
202     QString str;
203     str += QLatin1String("[");
204     for(int i = 0; i < m_array.count(); ++i) {
205         const QVariant &var = m_array[i];
206         str += apiVariantToString(var);
207         if (i < m_array.count() - 1)
208             str += QLatin1String(", ");
209     }
210     str += QLatin1String("]");
211
212     return str;
213 }
214
215 void ApiArray::init(const Trace::Array *arr)
216 {
217     if (!arr)
218         return;
219
220     for (int i = 0; i < arr->values.size(); ++i) {
221         VariantVisitor vis;
222         arr->values[i]->visit(vis);
223
224         m_array.append(vis.variant());
225     }
226 }
227
228 QStaticText ApiTraceCall::staticText() const
229 {
230     if (!m_staticText.text().isEmpty())
231         return m_staticText;
232
233     QString richText = QString::fromLatin1("<span style=\"font-weight:bold\">%1</span>(").arg(name);
234     for (int i = 0; i < argNames.count(); ++i) {
235         richText += QLatin1String("<span style=\"color:#0000ff\">");
236         richText += apiVariantToString(argValues[i]);
237         richText += QLatin1String("</span>");
238         if (i < argNames.count() - 1)
239             richText += QString::fromLatin1(", ");
240     }
241     richText += QLatin1String(")");
242
243     m_staticText.setText(richText);
244     QTextOption opt;
245     opt.setWrapMode(QTextOption::NoWrap);
246     m_staticText.setTextOption(opt);
247     m_staticText.prepare();
248
249     return m_staticText;
250 }
251
252 QString ApiTraceCall::toHtml() const
253 {
254     if (!m_richText.isEmpty())
255         return m_richText;
256
257     m_richText = QString::fromLatin1("<span style=\"font-weight:bold\">%1</span>(").arg(name);
258     for (int i = 0; i < argNames.count(); ++i) {
259         m_richText += argNames[i];
260         m_richText += QString::fromLatin1(" = ");
261         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
262         m_richText += apiVariantToString(argValues[i]);
263         m_richText += QLatin1String("</span>");
264         if (i < argNames.count() - 1)
265             m_richText += QString::fromLatin1(", ");
266     }
267     m_richText += QLatin1String(")");
268
269     if (returnValue.isValid()) {
270         m_richText += QLatin1String(" = ");
271         m_richText += QLatin1String("<span style=\"color:#0000ff\">");
272         m_richText += apiVariantToString(returnValue);
273         m_richText += QLatin1String("</span>");
274     }
275     return m_richText;
276 }
277
278 QString ApiTraceCall::filterText() const
279 {
280     if (!m_filterText.isEmpty())
281         return m_filterText;
282
283     m_filterText = name;
284     for (int i = 0; i < argNames.count(); ++i) {
285         m_filterText += argNames[i];
286         m_filterText += QString::fromLatin1(" = ");
287         m_filterText += apiVariantToString(argValues[i]);
288         if (i < argNames.count() - 1)
289             m_filterText += QString::fromLatin1(", ");
290     }
291     m_filterText += QLatin1String(")");
292
293     if (returnValue.isValid()) {
294         m_filterText += QLatin1String(" = ");
295         m_filterText += apiVariantToString(returnValue);
296     }
297     return m_filterText;
298 }
299
300 QStaticText ApiTraceFrame::staticText() const
301 {
302     if (!m_staticText.text().isEmpty())
303         return m_staticText;
304
305     QString richText =
306         QString::fromLatin1("<span style=\"font-weight:bold\">Frame %1</span>").arg(number);
307
308     m_staticText.setText(richText);
309     QTextOption opt;
310     opt.setWrapMode(QTextOption::NoWrap);
311     m_staticText.setTextOption(opt);
312     m_staticText.prepare();
313
314     return m_staticText;
315 }
316
317 int ApiTraceCall::numChildren() const
318 {
319     return 0;
320 }
321
322 int ApiTraceFrame::numChildren() const
323 {
324     return calls.count();
325 }
326
327 ApiTraceFrame::ApiTraceFrame()
328     : ApiTraceEvent(ApiTraceEvent::Frame)
329 {
330 }
331
332 ApiTraceCall::ApiTraceCall()
333     : ApiTraceEvent(ApiTraceEvent::Call)
334 {
335 }
336
337 ApiTraceEvent::ApiTraceEvent()
338     : m_type(ApiTraceEvent::None)
339 {
340 }
341
342 ApiTraceEvent::ApiTraceEvent(Type t)
343     : m_type(t)
344 {
345 }
346
347 ApiTraceCall::~ApiTraceCall()
348 {
349 }