source: flair-src/trunk/tools/FlairGCS/src/file_ui.cpp@ 244

Last change on this file since 244 was 244, checked in by Sanahuja Guillaume, 6 years ago

modifs segfault when closing connection

File size: 14.3 KB
RevLine 
[10]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[10]4// %flair:license}
[9]5#include "file_ui.h"
[234]6#include "communication.h"
7
[9]8#include <stdio.h>
9#include <cstring>
10#include <cstdlib>
11#include <fstream>
12#include <iostream>
13#include <QDir>
14#include <QDate>
15#include <QTextStream>
16#include <QGridLayout>
17#include <io_hdfile.h>
18#include <QtEndian>
19#include <QComboBox>
20#include <QPushButton>
21#include <QTextEdit>
22#include <QDialog>
23#include <QStringList>
24#include <QFormLayout>
[234]25#include <QThread>
[9]26
[234]27#include <unistd.h>
[9]28using namespace std;
29
[234]30file_ui::file_ui(UDTSOCKET socket,QString name): QObject() {
31 this->socket=socket;
32 this->name=name;
33
34 bool blocking = true;
35 if (UDT::setsockopt(socket, 0, UDT_SNDSYN, &blocking, sizeof(bool))!= 0) {
[244]36 fprintf(stderr,"UDT::setsockopt error (UDT_SNDSYN) %s\n",UDT::getlasterror().getErrorMessage());
[234]37 }
38
39 linger _linger;
40 _linger.l_onoff=1;
41 _linger.l_linger=180;
42
43 if (UDT::setsockopt(socket, 0, UDT_LINGER, &_linger, sizeof(struct linger)) != 0)
[244]44 fprintf(stderr,"UDT::setsockopt error (UDT_LINGER) %s\n",UDT::getlasterror().getErrorMessage());
[234]45
[15]46 dialog = new QDialog();
[244]47//ffprintf(stderr,stderr,"creator file ui %x\n",thread());
[15]48 dialog->setWindowTitle("log files");
49 QGridLayout *main_layout = new QGridLayout(dialog);
50 ok_button = new QPushButton("Ok", dialog);
51 log_text = new QTextEdit(dialog);
52 log_text->setReadOnly(true);
53 input_text = new QTextEdit(dialog);
54 input_text->setText("add your log comment here");
55 input_cleared = false;
56 ok_button->setEnabled(false);
[9]57
[15]58 main_layout->addWidget(log_text, 0, 0);
59 main_layout->addWidget(input_text, 1, 0);
[9]60
[15]61 QWidget *widget = new QWidget(dialog);
62 QFormLayout *formLayout = new QFormLayout(widget);
63 csv_combo = new QComboBox(widget);
64 formLayout->addRow(tr("save all log with following base time"), csv_combo);
65 csv_combo->addItem("(no base time)");
66 main_layout->addWidget(widget, 2, 0);
67 main_layout->addWidget(ok_button, 3, 0);
[9]68
[234]69 //connect for multithreaded stuffs
70 connect(ok_button, SIGNAL(clicked()), this, SLOT(save()),Qt::QueuedConnection);
71 connect(input_text, SIGNAL(cursorPositionChanged()), this,SLOT(clearInputText()),Qt::DirectConnection);
72 connect(this, SIGNAL(appendToLog(QString)), log_text, SLOT(append(QString)));
[9]73
[15]74 file_names = new QStringList();
[234]75
76 dialog->show();
[9]77}
78
[234]79file_ui::~file_ui() {
80 delete dialog;
81}
[9]82
[234]83void file_ui::receive(void) {
84 char *recv_buf;
85 int bytesRead;
86 bool flag_new_seq = true;
87 QString folder_name;
[244]88//ffprintf(stderr,stderr,"file_ui thread %x\n",thread());
[234]89 while(1) {
90 // receive file info
91 recv_buf = (char *)malloc(1024);
92 bytesRead = UDT::recvmsg(socket, recv_buf, 1024);
93 if (bytesRead <= 0) {
94 free(recv_buf);
95 break;
96 }
[9]97
[234]98 int size;
99 memcpy(&size, &recv_buf[1], sizeof(int));
100 if (recv_buf[0] == FILE_INFO_BIG_ENDIAN)
101 size = qFromBigEndian(size);
102
[244]103 // fprintf(stderr,"file_ui recu %i %x\n",bytesRead,recv_buf[0]);
[234]104 if ((recv_buf[0]==FILE_INFO_LITTLE_ENDIAN || recv_buf[0]==FILE_INFO_BIG_ENDIAN) && size>0) {
105 if (flag_new_seq == true) {
106 // create directory for storage
107 QDateTime dateTime = QDateTime::currentDateTime();
108 folder_name = dateTime.toString("yyyyMMdd_hhmm") + "_" + name;
109 if (QDir().exists(folder_name) == true) {
110 folder_name = dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name;
111 }
112 QDir().mkdir(folder_name);
113
114 flag_new_seq = false;
115 appendToLog("Creating directory " + folder_name);
116 }
117
118 QString file_name=QString::fromAscii((const char *)&recv_buf[5], bytesRead - 5);
119 QString file_path=folder_name+"/"+file_name;
120 appendToLog(QString("receiving %1 (%2 bytes)").arg(file_name).arg(size));
121 QFile fichier(file_path);
122
123 if (!fichier.open(QIODevice::WriteOnly)) {
124 appendToLog(" could not write to file!");
125 } else {
126 // receive file
127 recv_buf = (char *)realloc((void *)recv_buf, size);
128 bytesRead = UDT::recvmsg(socket, recv_buf, size);
129 if (bytesRead != size) {
130 appendToLog(QString(" error receiving file! (%1/%2)").arg(bytesRead).arg(size));
131 free(recv_buf);
132 break;
133 } else {
134 appendToLog(" ok");
135 }
136
137 QDataStream stream(&fichier);
138 stream.writeRawData(recv_buf, size);
139 fichier.close();
140
141 addFile(file_path);
142 }
143
144 free(recv_buf);
145 } else if (recv_buf[0] == END_SENDING_FILES) {
146 //end ack
147 UDT::sendmsg(socket,&recv_buf[0],1);
148 endOfFiles();
149 UDT::close(socket);
[244]150 fprintf(stderr,"disconnected from log files\n");
[234]151 break;
152 }
153 }
154}
155
[9]156void file_ui::addFile(QString file_path) {
[15]157 // framework sends dbt file then txt file
158 // when we receive txt, we have both files
159 // and we can convert it to .csv
160 if (file_path.endsWith(".dbt") == true) {
161 QString name =
162 file_path.section('/', -1); // remove path for displaying on combobox
163 csv_combo->addItem(name.replace(QString(".dbt"), QString(".csv")));
164 file_names->append(file_path.replace(QString(".dbt"), QString(".csv")));
165 }
[9]166
[15]167 if (file_path.endsWith(".txt") == true) {
168 dbt2csv(file_path.replace(QString(".txt"), QString(".dbt")));
169 }
[9]170}
171
172void file_ui::endOfFiles(void) {
[15]173 ok_button->setEnabled(true);
[9]174
[15]175 qint64 max_file_size = 0;
176 for (int i = 0; i < file_names->count(); i++) {
177 QFileInfo info(file_names->at(i));
178 if (info.size() > max_file_size) {
179 max_file_size = info.size();
[234]180 csv_combo->setCurrentIndex(i+1); // first item of combobox is already taken
[9]181 }
[15]182 }
[9]183}
184
[15]185void file_ui::dbt2csv(QString file_path) {
186 hdfile_t *dbtFile = NULL;
187 char *data;
188 QStringList data_type;
[9]189
[234]190 QString filename =file_path.section('/', -1); // remove path for displaying on logs
[15]191 appendToLog(QString("converting %1 to csv").arg(filename));
[9]192
[15]193 // open csv file
194 QString csv_filename = file_path;
195 csv_filename.replace(QString(".dbt"), QString(".csv"));
196 QFile csv_file(csv_filename);
[9]197
[15]198 if (!csv_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
199 appendToLog(" error opening csv file!");
200 return;
201 }
202 QTextStream out(&csv_file);
[9]203
[15]204 // open txt file
205 QString txt_filename = file_path;
206 txt_filename.replace(QString(".dbt"), QString(".txt"));
207 QFile txt_file(txt_filename);
[9]208
[15]209 if (!txt_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
210 appendToLog(" error opening txt file!");
211 return;
212 }
[9]213
[15]214 // read txt file
215 QTextStream txt_in(&txt_file);
216 txt_in.readLine(); // time us
217 txt_in.readLine(); // time ns
218 while (1) {
219 if (txt_in.atEnd() == true)
220 break;
221 QString txt_line = txt_in.readLine();
[234]222 data_type.append(txt_line.section("(",-1)); // on part de la fin pour trouver la premiere parenthese ouvrante
[244]223 // fprintf(stderr,"type %s\n",txt_line.section("(",-1).toLocal8Bit().constData());
[15]224 }
225 txt_file.close();
[9]226
[15]227 dbtFile = open_hdfile(file_path.toLocal8Bit().data(), READ_MODE);
[9]228
[15]229 if (!dbtFile) {
230 appendToLog(" error opening dbt file!");
231 return;
232 }
233 data = (char *)malloc(dbtFile->h.DataSize);
234 if (data == NULL) {
235 appendToLog(" error malloc!");
236 return;
237 }
[9]238
[15]239 bool dataWritten = false;
240 while (1) {
241 road_time_t time;
242 road_timerange_t tr = 0;
243 int offset = 0;
244 QTextStream csv_line;
[9]245
[15]246 if (read_hdfile(dbtFile, (void *)data, &time, &tr) == 0) {
247 break;
248 }
249 dataWritten = true;
[9]250
[15]251 out << time << "," << tr;
252 for (int i = 0; i < data_type.size(); i++) {
[51]253 if (data_type.at(i) == "double)") {
254 double *value = (double *)(data + offset);
255 offset += sizeof(double);
256 out << "," << *value;
257 } else if (data_type.at(i) == "float)") {
[15]258 float *value = (float *)(data + offset);
259 offset += sizeof(float);
260 out << "," << *value;
261 } else if (data_type.at(i) == "int8_t)") {
262 int8_t *value = (int8_t *)(data + offset);
263 offset += sizeof(int8_t);
264 out << "," << *value;
[51]265 } else if (data_type.at(i) == "uint8_t)") {
266 uint8_t *value = (uint8_t *)(data + offset);
267 offset += sizeof(uint8_t);
268 out << "," << *value;
[214]269 } else if (data_type.at(i) == "int16_t)") {
270 int16_t *value = (int16_t *)(data + offset);
271 offset += sizeof(int16_t);
272 out << "," << *value;
273 } else if (data_type.at(i) == "uint16_t)") {
274 uint16_t *value = (uint16_t *)(data + offset);
275 offset += sizeof(uint16_t);
276 out << "," << *value;
[15]277 } else {
278 appendToLog(QString(" unhandled type: %1").arg(data_type.at(i)));
279 }
[9]280 }
281
[15]282 out << "\n";
283 }
284
285 if (!dataWritten) {
286 // empty file!
287 out << "0,0"; // timr
288 for (int i = 0; i < data_type.size(); i++) {
289 out << ",0";
[9]290 }
[15]291 out << "\n";
292 }
[9]293
[15]294 csv_file.close();
295 close_hdfile(dbtFile);
296 if (data != NULL)
297 free(data);
[9]298
[15]299 appendToLog(" ok");
[9]300}
301
[15]302void file_ui::clearInputText(void) {
303 if (input_cleared == false) {
304 input_cleared = true;
305 input_text->clear();
306 }
[9]307}
308
[15]309void file_ui::save(void) {
310 save_comment();
311 if (csv_combo->currentIndex() != 0) {
312 save_csv();
313 save_txt();
314 }
[9]315
[15]316 emit finished();
[9]317}
318
[15]319void file_ui::save_comment(void) {
320 QString folder_name = file_names->at(0).section('/', 0, -2);
[9]321
[15]322 QString filename = folder_name + "/commentaire.txt";
323 QFile file(filename);
324 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
[244]325 fprintf(stderr,"file_ui::save_comment: erreur ouverture fichier %s\n",
[15]326 filename.toLocal8Bit().constData());
327 QTextStream out(&file);
[9]328
[15]329 out << input_text->toPlainText();
330 file.close();
[9]331}
332
[15]333void file_ui::save_csv(void) {
334 // global csv file
335 QString folder_name = file_names->at(0).section('/', 0, -2);
336 QString filename = folder_name + "/all_logs.csv";
337 QFile global_file(filename);
338 if (!global_file.open(QIODevice::WriteOnly | QIODevice::Text))
[244]339 fprintf(stderr,"file_ui::save_csv: erreur ouverture fichier %s\n",
[15]340 filename.toLocal8Bit().constData());
341 QTextStream out(&global_file);
[9]342
[15]343 // reference csv file
344 filename = file_names->at(csv_combo->currentIndex() - 1);
345 QFile ref_file(filename);
[244]346 // fprintf(stderr,"file_ui::save_csv: ref %s\n",filename.toLocal8Bit().constData());
[15]347 if (!ref_file.open(QIODevice::ReadOnly | QIODevice::Text))
[244]348 fprintf(stderr,"file_ui::save_csv: erreur ouverture ficher %s\n",
[15]349 filename.toLocal8Bit().constData());
[9]350
[15]351 // other csv files
352 int j = 0;
353 QFile m_file[file_names->count() - 1];
354 QTextStream m_in[file_names->count() - 1];
355 for (int i = 0; i < file_names->count(); i++) {
356 if (i == csv_combo->currentIndex() - 1)
357 continue;
358 filename = file_names->at(i);
359 m_file[j].setFileName(filename);
360 if (!m_file[j].open(QIODevice::ReadOnly | QIODevice::Text))
[244]361 fprintf(stderr,"file_ui::save_csv: erreur ouverture ficher %s\n",
[15]362 filename.toLocal8Bit().constData());
363 m_in[j].setDevice(&m_file[j]);
364 j++;
365 }
[9]366
[15]367 // init
368 QTextStream ref_in(&ref_file);
369 QString m_line[file_names->count() - 1];
370 QString m_line_prev[file_names->count() - 1];
371 for (int i = 0; i < file_names->count() - 1; i++) {
372 m_line[i] = m_in[i].readLine();
373 m_line_prev[i] = m_line[i];
374 }
[9]375
[15]376 // organize csv files in one file
377 while (1) {
378 if (ref_in.atEnd() == true)
379 break;
380 QString ref_line = ref_in.readLine();
[9]381
[15]382 qint64 ref_us = ref_line.section(',', 0, 0).toLongLong();
383 int ref_ns = ref_line.section(',', 1, 1).toInt();
[244]384 // fprintf(stderr,"ref %lld %i\n",ref_us,ref_ns);
[9]385
[15]386 for (int i = 0; i < file_names->count() - 1; i++) {
387 qint64 csv_us = m_line[i].section(',', 0, 0).toLongLong();
388 int csv_ns = m_line[i].section(',', 1, 1).toInt();
[244]389 // fprintf(stderr,"m %lld %i\n",csv_us,csv_ns);
[9]390
[15]391 while (is_greater(ref_us, csv_us, ref_ns, csv_ns) == true) {
392 m_line_prev[i] = m_line[i];
393 if (m_in[i].atEnd() == true)
394 break;
395 m_line[i] = m_in[i].readLine();
396 csv_us = m_line[i].section(',', 0, 0).toLongLong();
397 csv_ns = m_line[i].section(',', 1, 1).toInt();
[244]398 // fprintf(stderr,"m %lld %i\n",csv_us,csv_ns);
[15]399 }
400 csv_us = m_line_prev[i].section(',', 0, 0).toLongLong();
401 csv_ns = m_line_prev[i].section(',', 1, 1).toInt();
[244]402 // fprintf(stderr,"m ok %lld %i\n",csv_us,csv_ns);
[9]403
[15]404 ref_line += "," + m_line_prev[i].section(',', 2);
[9]405 }
406
[15]407 out << ref_line << "\n";
408 }
409
410 global_file.close();
411 ref_file.close();
412 for (int i = 0; i < file_names->count() - 1; i++)
413 m_file[i].close();
[9]414}
415
[15]416void file_ui::save_txt(void) {
417 // global txt file
418 QString folder_name = file_names->at(0).section('/', 0, -2);
419 QString filename = folder_name + "/all_logs.txt";
420 QFile global_file(filename);
421 if (!global_file.open(QIODevice::WriteOnly | QIODevice::Text))
[244]422 fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
[15]423 filename.toLocal8Bit().constData());
424 QTextStream out(&global_file);
[9]425
[15]426 // reference txt file
427 filename = file_names->at(csv_combo->currentIndex() - 1);
428 filename.replace(QString(".csv"), QString(".txt"));
429 QFile ref_file(filename);
430 if (!ref_file.open(QIODevice::ReadOnly | QIODevice::Text))
[244]431 fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
[15]432 filename.toLocal8Bit().constData());
[9]433
[15]434 QTextStream ref_in(&ref_file);
435 QString current_line = ref_in.readLine();
436 int nb_lines = 1;
437 while (current_line != NULL) {
438 out << current_line << "\n";
439 ;
440 current_line = ref_in.readLine();
441 nb_lines++;
442 }
[9]443
[15]444 // other txt files
445 for (int i = 0; i < file_names->count(); i++) {
446 if (i == csv_combo->currentIndex() - 1)
447 continue;
448 filename = file_names->at(i);
449 filename.replace(QString(".csv"), QString(".txt"));
450 QFile txt_file(filename);
451 if (!txt_file.open(QIODevice::ReadOnly | QIODevice::Text))
[244]452 fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
[15]453 filename.toLocal8Bit().constData());
454 QTextStream txt_in(&txt_file);
455 txt_in.readLine(); // time us
456 txt_in.readLine(); // time ns
457 current_line = txt_in.readLine();
458 while (current_line != NULL) {
459 out << nb_lines << ":" << current_line.section(':', 1) << "\n";
460 ;
461 current_line = txt_in.readLine();
462 nb_lines++;
[9]463 }
[15]464 txt_file.close();
465 }
466 global_file.close();
467 ref_file.close();
[9]468}
469
[15]470bool file_ui::is_greater(qint64 ref_us, qint64 csv_us, int ref_ns, int csv_ns) {
471 if (ref_us == csv_us) {
472 if (ref_ns > csv_ns) {
473 return true;
474 } else {
475 return false;
[9]476 }
[15]477 }
478 if (ref_us > csv_us) {
479 return true;
480 } else {
481 return false;
482 }
[9]483}
Note: See TracBrowser for help on using the repository browser.