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