blob: ad8f48a67c3d4927c8bbcc390bb808ddf1134a98 [file] [log] [blame]
Zack Rusinc6247dd2011-04-17 22:56:58 -04001#include "saverthread.h"
2
José Fonseca9ed67222011-05-24 08:42:59 +01003#include "trace_writer.hpp"
Zack Rusin9b31ffc2011-09-13 23:58:45 -04004#include "trace_model.hpp"
5#include "trace_parser.hpp"
Zack Rusinc6247dd2011-04-17 22:56:58 -04006
7#include <QFile>
8#include <QHash>
9#include <QUrl>
10
11#include <QDebug>
12
Zack Rusin9b31ffc2011-09-13 23:58:45 -040013#if 0
José Fonsecab4a3d142011-10-27 07:43:19 +010014static trace::FunctionSig *
Zack Rusinc6247dd2011-04-17 22:56:58 -040015createFunctionSig(ApiTraceCall *call, unsigned id)
16{
José Fonsecab4a3d142011-10-27 07:43:19 +010017 trace::FunctionSig *sig = new trace::FunctionSig();
Zack Rusinc6247dd2011-04-17 22:56:58 -040018
19 sig->id = id;
20 sig->name = qstrdup(call->name().toLocal8Bit());
21
22 QStringList args = call->argNames();
23 sig->num_args = args.count();
José Fonseca00914322011-05-28 13:10:13 +010024 sig->arg_names = new const char*[args.count()];
Zack Rusinc6247dd2011-04-17 22:56:58 -040025 for (int i = 0; i < args.count(); ++i) {
José Fonseca00914322011-05-28 13:10:13 +010026 sig->arg_names[i] = qstrdup(args[i].toLocal8Bit());
Zack Rusinc6247dd2011-04-17 22:56:58 -040027 }
28
29 return sig;
30}
31
32static void
José Fonsecab4a3d142011-10-27 07:43:19 +010033deleteFunctionSig(trace::FunctionSig *sig)
Zack Rusinc6247dd2011-04-17 22:56:58 -040034{
35 for (int i = 0; i < sig->num_args; ++i) {
José Fonseca00914322011-05-28 13:10:13 +010036 delete [] sig->arg_names[i];
Zack Rusinc6247dd2011-04-17 22:56:58 -040037 }
José Fonseca00914322011-05-28 13:10:13 +010038 delete [] sig->arg_names;
Zack Rusinc6247dd2011-04-17 22:56:58 -040039 delete [] sig->name;
40 delete sig;
41}
42
José Fonsecab4a3d142011-10-27 07:43:19 +010043static trace::StructSig *
Zack Rusinc6247dd2011-04-17 22:56:58 -040044createStructSig(const ApiStruct &str, unsigned id)
45{
46 ApiStruct::Signature aSig = str.signature();
47
José Fonsecab4a3d142011-10-27 07:43:19 +010048 trace::StructSig *sig = new trace::StructSig();
Zack Rusinc6247dd2011-04-17 22:56:58 -040049 sig->id = id;
50 sig->name = qstrdup(aSig.name.toLocal8Bit());
51 sig->num_members = aSig.memberNames.count();
José Fonseca1b23ed22011-05-28 13:01:16 +010052 char **member_names = new char*[aSig.memberNames.count()];
53 sig->member_names = (const char **)member_names;
Zack Rusinc6247dd2011-04-17 22:56:58 -040054 for (int i = 0; i < aSig.memberNames.count(); ++i) {
José Fonseca1b23ed22011-05-28 13:01:16 +010055 member_names[i] = qstrdup(aSig.memberNames[i].toLocal8Bit());
Zack Rusinc6247dd2011-04-17 22:56:58 -040056 }
57 return sig;
58}
59
60static void
José Fonsecab4a3d142011-10-27 07:43:19 +010061deleteStructSig(trace::StructSig *sig)
Zack Rusinc6247dd2011-04-17 22:56:58 -040062{
63 for (int i = 0; i < sig->num_members; ++i) {
José Fonseca1b23ed22011-05-28 13:01:16 +010064 delete [] sig->member_names[i];
Zack Rusinc6247dd2011-04-17 22:56:58 -040065 }
José Fonseca1b23ed22011-05-28 13:01:16 +010066 delete [] sig->member_names;
Zack Rusinc6247dd2011-04-17 22:56:58 -040067 delete [] sig->name;
68 delete sig;
69}
70
José Fonsecab4a3d142011-10-27 07:43:19 +010071static trace::EnumSig *
Zack Rusinc6247dd2011-04-17 22:56:58 -040072createEnumSig(const ApiEnum &en, unsigned id)
73{
José Fonsecab4a3d142011-10-27 07:43:19 +010074 trace::EnumSig *sig = new trace::EnumSig();
Zack Rusinc6247dd2011-04-17 22:56:58 -040075
76 sig->id = id;
77 sig->name = qstrdup(en.name().toLocal8Bit());
78 sig->value = en.value().toLongLong();
79
80 return sig;
81}
82
83static void
José Fonsecab4a3d142011-10-27 07:43:19 +010084deleteEnumSig(trace::EnumSig *sig)
Zack Rusinc6247dd2011-04-17 22:56:58 -040085{
86 delete [] sig->name;
87 delete sig;
88}
89
José Fonsecab4a3d142011-10-27 07:43:19 +010090static trace::BitmaskSig *
Zack Rusinc6247dd2011-04-17 22:56:58 -040091createBitmaskSig(const ApiBitmask &bt, unsigned id)
92{
93 ApiBitmask::Signature bsig = bt.signature();
94 ApiBitmask::Signature::const_iterator itr;
95
José Fonsecab4a3d142011-10-27 07:43:19 +010096 trace::BitmaskSig *sig = new trace::BitmaskSig();
97 trace::BitmaskFlag *flags = new trace::BitmaskFlag[bsig.count()];
Zack Rusinc6247dd2011-04-17 22:56:58 -040098
99 sig->id = id;
José Fonsecafcfbf172011-05-28 13:20:01 +0100100 sig->num_flags = bsig.count();
101 sig->flags = flags;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400102
103 int i = 0;
Zack Rusind809a062011-04-17 23:30:58 -0400104 for (itr = bsig.constBegin(); itr != bsig.constEnd(); ++itr, ++i) {
José Fonsecafcfbf172011-05-28 13:20:01 +0100105 flags[i].name = qstrdup(itr->first.toLocal8Bit());
106 flags[i].value = itr->second;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400107 }
108
109 return sig;
110}
111
112static void
José Fonsecab4a3d142011-10-27 07:43:19 +0100113deleteBitmaskSig(trace::BitmaskSig *sig)
Zack Rusinc6247dd2011-04-17 22:56:58 -0400114{
José Fonsecafcfbf172011-05-28 13:20:01 +0100115 for (int i = 0; i < sig->num_flags; ++i) {
116 delete [] sig->flags[i].name;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400117 }
José Fonsecafcfbf172011-05-28 13:20:01 +0100118 delete [] sig->flags;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400119 delete sig;
120}
121
122static void
José Fonsecab4a3d142011-10-27 07:43:19 +0100123writeValue(trace::Writer &writer, const QVariant &var, unsigned &id)
Zack Rusinc6247dd2011-04-17 22:56:58 -0400124{
125 int arrayType = QMetaType::type("ApiArray");
126 int bitmaskType = QMetaType::type("ApiBitmask");
127 int structType = QMetaType::type("ApiStruct");
128 int pointerType = QMetaType::type("ApiPointer");
129 int enumType = QMetaType::type("ApiEnum");
130 int type = var.userType();
131
132 switch(type) {
133 case QVariant::Bool:
José Fonsecaeced7472011-05-28 10:37:12 +0100134 writer.writeBool(var.toBool());
Zack Rusind809a062011-04-17 23:30:58 -0400135 break;
136 case QVariant::ByteArray: {
137 QByteArray ba = var.toByteArray();
José Fonsecaeced7472011-05-28 10:37:12 +0100138 writer.writeBlob((const void*)ba.constData(), ba.size());
Zack Rusind809a062011-04-17 23:30:58 -0400139 }
140 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400141 case QVariant::Double:
José Fonsecaeced7472011-05-28 10:37:12 +0100142 writer.writeDouble(var.toDouble());
Zack Rusind809a062011-04-17 23:30:58 -0400143 break;
144 case QMetaType::Float:
José Fonsecaeced7472011-05-28 10:37:12 +0100145 writer.writeFloat(var.toFloat());
Zack Rusind809a062011-04-17 23:30:58 -0400146 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400147 case QVariant::Int:
José Fonsecaeced7472011-05-28 10:37:12 +0100148 writer.writeSInt(var.toInt());
Zack Rusind809a062011-04-17 23:30:58 -0400149 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400150 case QVariant::LongLong:
José Fonsecaeced7472011-05-28 10:37:12 +0100151 writer.writeSInt(var.toLongLong());
Zack Rusind809a062011-04-17 23:30:58 -0400152 break;
153 case QVariant::String: {
154 QString str = var.toString();
José Fonsecaeced7472011-05-28 10:37:12 +0100155 writer.writeString(str.toLocal8Bit().constData(), str.length());
Zack Rusind809a062011-04-17 23:30:58 -0400156 }
157 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400158 case QVariant::UInt:
José Fonsecaeced7472011-05-28 10:37:12 +0100159 writer.writeUInt(var.toInt());
Zack Rusind809a062011-04-17 23:30:58 -0400160 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400161 case QVariant::ULongLong:
José Fonsecaeced7472011-05-28 10:37:12 +0100162 writer.writeUInt(var.toLongLong());
Zack Rusind809a062011-04-17 23:30:58 -0400163 break;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400164 default:
165 if (type == arrayType) {
166 ApiArray array = var.value<ApiArray>();
Zack Rusin77ff98a2011-08-28 22:30:35 -0400167 QVector<QVariant> vals = array.values();
José Fonsecaeced7472011-05-28 10:37:12 +0100168 writer.beginArray(vals.count());
Zack Rusinc6247dd2011-04-17 22:56:58 -0400169 foreach(QVariant el, vals) {
José Fonsecaeced7472011-05-28 10:37:12 +0100170 writer.beginElement();
171 writeValue(writer, el, ++id);
172 writer.endElement();
Zack Rusinc6247dd2011-04-17 22:56:58 -0400173 }
José Fonsecaeced7472011-05-28 10:37:12 +0100174 writer.endArray();
Zack Rusinc6247dd2011-04-17 22:56:58 -0400175 } else if (type == bitmaskType) {
176 ApiBitmask bm = var.value<ApiBitmask>();
José Fonsecab4a3d142011-10-27 07:43:19 +0100177 trace::BitmaskSig *sig = createBitmaskSig(bm, ++id);
José Fonseca466753b2011-05-28 13:25:55 +0100178 writer.writeBitmask(sig, bm.value());
Zack Rusinc6247dd2011-04-17 22:56:58 -0400179 deleteBitmaskSig(sig);
180 } else if (type == structType) {
181 ApiStruct apiStr = var.value<ApiStruct>();
182 QList<QVariant> vals = apiStr.values();
José Fonsecab4a3d142011-10-27 07:43:19 +0100183 trace::StructSig *str = createStructSig(apiStr, ++id);
José Fonsecaeced7472011-05-28 10:37:12 +0100184 writer.beginStruct(str);
Zack Rusinc6247dd2011-04-17 22:56:58 -0400185 foreach(QVariant val, vals) {
José Fonsecaeced7472011-05-28 10:37:12 +0100186 writeValue(writer, val, ++id);
Zack Rusinc6247dd2011-04-17 22:56:58 -0400187 }
José Fonsecaeced7472011-05-28 10:37:12 +0100188 writer.endStruct();
Zack Rusinc6247dd2011-04-17 22:56:58 -0400189 deleteStructSig(str);
190 } else if (type == pointerType) {
191 ApiPointer apiPtr = var.value<ApiPointer>();
José Fonsecad559f022012-04-15 16:13:51 +0100192 writer.writePointer(apiPtr.value());
Zack Rusinc6247dd2011-04-17 22:56:58 -0400193 } else if (type == enumType) {
194 ApiEnum apiEnum = var.value<ApiEnum>();
José Fonsecab4a3d142011-10-27 07:43:19 +0100195 trace::EnumSig *sig = createEnumSig(apiEnum, ++id);
José Fonsecaeced7472011-05-28 10:37:12 +0100196 writer.writeEnum(sig);
Zack Rusinc6247dd2011-04-17 22:56:58 -0400197 deleteEnumSig(sig);
Zack Rusinc6247dd2011-04-17 22:56:58 -0400198 } else {
199 qWarning()<<"Unsupported write variant : "
200 << QMetaType::typeName(type);
201 }
202 }
Zack Rusinc6247dd2011-04-17 22:56:58 -0400203}
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400204#endif
205
José Fonsecab4a3d142011-10-27 07:43:19 +0100206class EditVisitor : public trace::Visitor
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400207{
208public:
209 EditVisitor(const QVariant &variant)
210 : m_variant(variant),
211 m_editedValue(0)
212 {}
Jose Fonseca010f9962016-03-05 14:45:41 +0000213 virtual void visit(trace::Null *val) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400214 {
215 m_editedValue = val;
216 }
217
Jose Fonseca010f9962016-03-05 14:45:41 +0000218 virtual void visit(trace::Bool *node) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400219 {
220// Q_ASSERT(m_variant.userType() == QVariant::Bool);
221 bool var = m_variant.toBool();
José Fonsecab4a3d142011-10-27 07:43:19 +0100222 m_editedValue = new trace::Bool(var);
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400223 }
224
Jose Fonseca010f9962016-03-05 14:45:41 +0000225 virtual void visit(trace::SInt *node) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400226 {
227// Q_ASSERT(m_variant.userType() == QVariant::Int);
José Fonsecab4a3d142011-10-27 07:43:19 +0100228 m_editedValue = new trace::SInt(m_variant.toInt());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400229 }
230
Jose Fonseca010f9962016-03-05 14:45:41 +0000231 virtual void visit(trace::UInt *node) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400232 {
233// Q_ASSERT(m_variant.userType() == QVariant::UInt);
José Fonsecab4a3d142011-10-27 07:43:19 +0100234 m_editedValue = new trace::SInt(m_variant.toUInt());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400235 }
236
Jose Fonseca010f9962016-03-05 14:45:41 +0000237 virtual void visit(trace::Float *node) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400238 {
José Fonsecab4a3d142011-10-27 07:43:19 +0100239 m_editedValue = new trace::Float(m_variant.toFloat());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400240 }
241
Jose Fonseca010f9962016-03-05 14:45:41 +0000242 virtual void visit(trace::Double *node) override
Carl Worthe935ee12011-11-17 14:04:16 -0800243 {
244 m_editedValue = new trace::Double(m_variant.toDouble());
245 }
246
Jose Fonseca010f9962016-03-05 14:45:41 +0000247 virtual void visit(trace::String *node) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400248 {
249 QString str = m_variant.toString();
Zack Rusinc65f6dd2012-07-06 15:53:29 -0400250 char *newString = new char[str.length() + 1];
251 QByteArray ba = str.toLocal8Bit();
252 strcpy(newString, ba.constData());
253 m_editedValue = new trace::String(newString);
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400254 }
255
Jose Fonseca010f9962016-03-05 14:45:41 +0000256 virtual void visit(trace::WString *node) override
José Fonsecad5cda7c2014-09-25 15:19:09 +0100257 {
258 QString str = m_variant.toString();
259 size_t len = str.length();
260 wchar_t *newString = new wchar_t[len + 1];
261 str.toWCharArray(newString);
262 newString[len] = 0;
263 m_editedValue = new trace::WString(newString);
264 }
265
Jose Fonseca010f9962016-03-05 14:45:41 +0000266 virtual void visit(trace::Enum *e) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400267 {
268 m_editedValue = e;
269 }
270
Jose Fonseca010f9962016-03-05 14:45:41 +0000271 virtual void visit(trace::Bitmask *bitmask) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400272 {
273 m_editedValue = bitmask;
274 }
275
Jose Fonseca010f9962016-03-05 14:45:41 +0000276 virtual void visit(trace::Struct *str) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400277 {
278 m_editedValue = str;
279 }
280
Jose Fonseca010f9962016-03-05 14:45:41 +0000281 virtual void visit(trace::Array *array) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400282 {
283 ApiArray apiArray = m_variant.value<ApiArray>();
284 QVector<QVariant> vals = apiArray.values();
285
José Fonsecab4a3d142011-10-27 07:43:19 +0100286 trace::Array *newArray = new trace::Array(vals.count());
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400287 for (int i = 0; i < vals.count(); ++i) {
288 EditVisitor visitor(vals[i]);
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400289 array->values[i]->visit(visitor);
290 if (array->values[i] == visitor.value()) {
291 //non-editabled
292 delete newArray;
293 m_editedValue = array;
294 return;
295 }
296
Zack Rusinc65f6dd2012-07-06 15:53:29 -0400297 newArray->values[i] = visitor.value();
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400298 }
299 m_editedValue = newArray;
300 }
301
Jose Fonseca010f9962016-03-05 14:45:41 +0000302 virtual void visit(trace::Blob *blob) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400303 {
304 m_editedValue = blob;
305 }
306
Jose Fonseca010f9962016-03-05 14:45:41 +0000307 virtual void visit(trace::Pointer *ptr) override
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400308 {
309 m_editedValue = ptr;
310 }
311
José Fonsecab4a3d142011-10-27 07:43:19 +0100312 trace::Value *value() const
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400313 {
314 return m_editedValue;
315 }
316private:
317 QVariant m_variant;
José Fonsecab4a3d142011-10-27 07:43:19 +0100318 trace::Value *m_editedValue;
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400319};
320
321static void
José Fonsecab4a3d142011-10-27 07:43:19 +0100322overwriteValue(trace::Call *call, const QVariant &val, int index)
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400323{
324 EditVisitor visitor(val);
Carl Wortha5b476e2011-11-16 17:22:40 -0800325 trace::Value *origValue = call->args[index].value;
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400326 origValue->visit(visitor);
327
328 if (visitor.value() && origValue != visitor.value()) {
329 delete origValue;
Carl Wortha5b476e2011-11-16 17:22:40 -0800330 call->args[index].value = visitor.value();
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400331 }
332}
Zack Rusinc6247dd2011-04-17 22:56:58 -0400333
Zack Rusinc6247dd2011-04-17 22:56:58 -0400334SaverThread::SaverThread(QObject *parent)
335 : QThread(parent)
336{
337}
338
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400339void SaverThread::saveFile(const QString &writeFileName,
340 const QString &readFileName,
341 const QSet<ApiTraceCall*> &editedCalls)
Zack Rusinc6247dd2011-04-17 22:56:58 -0400342{
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400343 m_writeFileName = writeFileName;
344 m_readFileName = readFileName;
345 m_editedCalls = editedCalls;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400346 start();
347}
348
349void SaverThread::run()
350{
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400351 qDebug() << "Saving " << m_readFileName
352 << ", to " << m_writeFileName;
353 QMap<int, ApiTraceCall*> callIndexMap;
Zack Rusinc6247dd2011-04-17 22:56:58 -0400354
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400355 foreach(ApiTraceCall *call, m_editedCalls) {
356 callIndexMap.insert(call->index(), call);
Zack Rusinc6247dd2011-04-17 22:56:58 -0400357 }
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400358
José Fonsecab4a3d142011-10-27 07:43:19 +0100359 trace::Parser parser;
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400360 parser.open(m_readFileName.toLocal8Bit());
361
Jose Fonseca0d547e02017-08-03 18:10:22 +0100362 trace::Writer writer;
Jose Fonseca7301ab12017-08-03 18:25:53 +0100363 writer.open(m_writeFileName.toLocal8Bit(), parser.getVersion(), parser.getProperties());
Jose Fonseca0d547e02017-08-03 18:10:22 +0100364
José Fonsecab4a3d142011-10-27 07:43:19 +0100365 trace::Call *call;
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400366 while ((call = parser.parse_call())) {
367 if (callIndexMap.contains(call->no)) {
368 QVector<QVariant> values = callIndexMap[call->no]->editedValues();
369 for (int i = 0; i < values.count(); ++i) {
370 const QVariant &val = values[i];
371 overwriteValue(call, val, i);
372 }
Zack Rusinc5b741c2011-09-14 01:45:01 -0400373 writer.writeCall(call);
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400374 } else {
375 writer.writeCall(call);
376 }
James Legg453eff92015-06-05 21:33:08 +0100377 delete call;
Zack Rusin9b31ffc2011-09-13 23:58:45 -0400378 }
379
José Fonsecaeced7472011-05-28 10:37:12 +0100380 writer.close();
Zack Rusinc6247dd2011-04-17 22:56:58 -0400381
Zack Rusin9af5bff2011-04-18 01:05:50 -0400382 emit traceSaved();
Zack Rusinc6247dd2011-04-17 22:56:58 -0400383}
384
385#include "saverthread.moc"