Open/Save Progress Dialog done
This commit is contained in:
parent
1e805661fc
commit
00e03a44fd
103
client/port.cpp
103
client/port.cpp
@ -22,10 +22,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "abstractfileformat.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QProgressDialog>
|
||||
#include <QVariant>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <vector>
|
||||
|
||||
extern QMainWindow *mainWindow;
|
||||
|
||||
uint Port::mAllocStreamId = 0;
|
||||
|
||||
uint Port::newStreamId()
|
||||
@ -225,52 +229,137 @@ void Port::updateStats(OstProto::PortStats *portStats)
|
||||
|
||||
bool Port::openStreams(QString fileName, bool append, QString &error)
|
||||
{
|
||||
bool ret = false;
|
||||
QProgressDialog progress("Opening Streams", "Cancel", 0, 0, mainWindow);
|
||||
OstProto::StreamConfigList streams;
|
||||
AbstractFileFormat *fmt = AbstractFileFormat::fileFormatFromFile(fileName);
|
||||
|
||||
if (fmt == NULL)
|
||||
goto _fail;
|
||||
|
||||
if (!fmt->openStreams(fileName, streams, error))
|
||||
progress.setAutoReset(false);
|
||||
progress.setAutoClose(false);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.show();
|
||||
|
||||
mainWindow->setDisabled(true);
|
||||
progress.setEnabled(true); // to override the mainWindow disable
|
||||
|
||||
connect(fmt, SIGNAL(status(QString)),&progress,SLOT(setLabelText(QString)));
|
||||
connect(fmt, SIGNAL(target(int)), &progress, SLOT(setMaximum(int)));
|
||||
connect(fmt, SIGNAL(progress(int)), &progress, SLOT(setValue(int)));
|
||||
connect(&progress, SIGNAL(canceled()), fmt, SLOT(cancel()));
|
||||
|
||||
fmt->openStreamsOffline(fileName, streams, error);
|
||||
qDebug("after open offline");
|
||||
|
||||
while (!fmt->isFinished())
|
||||
qApp->processEvents();
|
||||
qDebug("wait over for offline operation");
|
||||
|
||||
if (!fmt->result())
|
||||
goto _fail;
|
||||
|
||||
// process any remaining events posted from the thread
|
||||
for (int i = 0; i < 10; i++)
|
||||
qApp->processEvents();
|
||||
|
||||
if (!append)
|
||||
{
|
||||
while (numStreams())
|
||||
int n = numStreams();
|
||||
|
||||
progress.setLabelText("Deleting existing streams...");
|
||||
progress.setRange(0, n);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
if (progress.wasCanceled())
|
||||
goto _user_cancel;
|
||||
deleteStreamAt(0);
|
||||
progress.setValue(i);
|
||||
if (i % 32 == 0)
|
||||
qApp->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
progress.setLabelText("Constructing new streams...");
|
||||
progress.setRange(0, streams.stream_size());
|
||||
for (int i = 0; i < streams.stream_size(); i++)
|
||||
{
|
||||
if (progress.wasCanceled())
|
||||
goto _user_cancel;
|
||||
newStreamAt(mStreams.size(), &streams.stream(i));
|
||||
progress.setValue(i);
|
||||
if (i % 32 == 0)
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
_user_cancel:
|
||||
emit streamListChanged(mPortGroupId, mPortId);
|
||||
|
||||
return true;
|
||||
ret = true;
|
||||
|
||||
_fail:
|
||||
return false;
|
||||
progress.close();
|
||||
mainWindow->setEnabled(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Port::saveStreams(QString fileName, QString fileType, QString &error)
|
||||
{
|
||||
bool ret = false;
|
||||
QProgressDialog progress("Saving Streams", "Cancel", 0, 0, mainWindow);
|
||||
AbstractFileFormat *fmt = AbstractFileFormat::fileFormatFromType(fileType);
|
||||
OstProto::StreamConfigList streams;
|
||||
|
||||
if (fmt == NULL)
|
||||
goto _fail;
|
||||
|
||||
progress.setAutoReset(false);
|
||||
progress.setAutoClose(false);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.show();
|
||||
|
||||
mainWindow->setDisabled(true);
|
||||
progress.setEnabled(true); // to override the mainWindow disable
|
||||
|
||||
connect(fmt, SIGNAL(status(QString)),&progress,SLOT(setLabelText(QString)));
|
||||
connect(fmt, SIGNAL(target(int)), &progress, SLOT(setMaximum(int)));
|
||||
connect(fmt, SIGNAL(progress(int)), &progress, SLOT(setValue(int)));
|
||||
connect(&progress, SIGNAL(canceled()), fmt, SLOT(cancel()));
|
||||
|
||||
progress.setLabelText("Preparing Streams...");
|
||||
progress.setRange(0, mStreams.size());
|
||||
streams.mutable_port_id()->set_id(0);
|
||||
for (int i = 0; i < mStreams.size(); i++)
|
||||
{
|
||||
OstProto::Stream *s = streams.add_stream();
|
||||
mStreams[i]->protoDataCopyInto(*s);
|
||||
|
||||
if (progress.wasCanceled())
|
||||
goto _user_cancel;
|
||||
progress.setValue(i);
|
||||
if (i % 32 == 0)
|
||||
qApp->processEvents();
|
||||
}
|
||||
|
||||
return fmt->saveStreams(streams, fileName, error);
|
||||
fmt->saveStreamsOffline(streams, fileName, error);
|
||||
qDebug("after save offline");
|
||||
|
||||
while (!fmt->isFinished())
|
||||
qApp->processEvents();
|
||||
qDebug("wait over for offline operation");
|
||||
|
||||
ret = fmt->result();
|
||||
goto _exit;
|
||||
|
||||
_user_cancel:
|
||||
goto _exit;
|
||||
|
||||
_fail:
|
||||
error = QString("Unsupported File Type - %1").arg(fileType);
|
||||
return false;
|
||||
goto _exit;
|
||||
|
||||
_exit:
|
||||
progress.close();
|
||||
mainWindow->setEnabled(true);
|
||||
return ret;
|
||||
}
|
||||
|
@ -458,14 +458,15 @@ void PortsWindow::on_actionOpen_Streams_triggered()
|
||||
|
||||
Q_ASSERT(plm->isPort(current));
|
||||
|
||||
fileName = QFileDialog::getOpenFileName(this, tr("Open Streams"));
|
||||
fileName = QFileDialog::getOpenFileName(this, tr("Open Streams"), "D:/srivatsp/projects/ostinato/testfiles/pcaps");
|
||||
if (fileName.isEmpty())
|
||||
goto _exit;
|
||||
|
||||
if (tvStreamList->model()->rowCount())
|
||||
{
|
||||
QMessageBox msgBox(QMessageBox::Question, qApp->applicationName(),
|
||||
tr("Append to existing streams? Or overwrite?"));
|
||||
tr("Append to existing streams? Or overwrite?"),
|
||||
QMessageBox::NoButton, this);
|
||||
QPushButton *appendBtn = msgBox.addButton(tr("Append"),
|
||||
QMessageBox::ActionRole);
|
||||
QPushButton *overwriteBtn = msgBox.addButton(tr("Overwrite"),
|
||||
|
@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
AbstractFileFormat::AbstractFileFormat()
|
||||
{
|
||||
stop_ = false;
|
||||
}
|
||||
|
||||
AbstractFileFormat::~AbstractFileFormat()
|
||||
@ -40,10 +41,40 @@ QStringList AbstractFileFormat::supportedFileTypes()
|
||||
<< "PCAP (*)"
|
||||
<< "PDML (*.pdml)";
|
||||
}
|
||||
|
||||
void AbstractFileFormat::openStreamsOffline(const QString fileName,
|
||||
OstProto::StreamConfigList &streams, QString &error)
|
||||
{
|
||||
fileName_ = fileName;
|
||||
openStreams_ = &streams;
|
||||
error_ = &error;
|
||||
op_ = kOpen;
|
||||
stop_ = false;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void AbstractFileFormat::saveStreamsOffline(
|
||||
const OstProto::StreamConfigList streams,
|
||||
const QString fileName, QString &error)
|
||||
{
|
||||
saveStreams_ = streams;
|
||||
fileName_ = fileName;
|
||||
error_ = &error;
|
||||
op_ = kSave;
|
||||
stop_ = false;
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
bool AbstractFileFormat::result()
|
||||
{
|
||||
return result_;
|
||||
}
|
||||
|
||||
AbstractFileFormat* AbstractFileFormat::fileFormatFromFile(
|
||||
const QString fileName)
|
||||
{
|
||||
|
||||
if (fileFormat.isMyFileFormat(fileName))
|
||||
return &fileFormat;
|
||||
|
||||
@ -71,3 +102,16 @@ AbstractFileFormat* AbstractFileFormat::fileFormatFromType(
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AbstractFileFormat::cancel()
|
||||
{
|
||||
stop_ = true;
|
||||
}
|
||||
|
||||
void AbstractFileFormat::run()
|
||||
{
|
||||
if (op_ == kOpen)
|
||||
result_ = openStreams(fileName_, *openStreams_, *error_);
|
||||
else if (op_ == kSave)
|
||||
result_ = saveStreams(saveStreams_, fileName_, *error_);
|
||||
}
|
||||
|
@ -22,12 +22,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "protocol.pb.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QString>
|
||||
|
||||
class AbstractFileFormat : public QObject
|
||||
class AbstractFileFormat : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
AbstractFileFormat();
|
||||
virtual ~AbstractFileFormat();
|
||||
@ -37,6 +37,13 @@ public:
|
||||
virtual bool saveStreams(const OstProto::StreamConfigList streams,
|
||||
const QString fileName, QString &error) = 0;
|
||||
|
||||
void openStreamsOffline(const QString fileName,
|
||||
OstProto::StreamConfigList &streams, QString &error);
|
||||
void saveStreamsOffline(const OstProto::StreamConfigList streams,
|
||||
const QString fileName, QString &error);
|
||||
|
||||
bool result();
|
||||
|
||||
static AbstractFileFormat* fileFormatFromFile(const QString fileName);
|
||||
static AbstractFileFormat* fileFormatFromType(const QString fileType);
|
||||
|
||||
@ -46,6 +53,33 @@ public:
|
||||
bool isMyFileFormat(const QString fileName) = 0;
|
||||
bool isMyFileType(const QString fileType) = 0;
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void status(QString text);
|
||||
void target(int value);
|
||||
void progress(int value);
|
||||
|
||||
public slots:
|
||||
void cancel();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
bool stop_;
|
||||
|
||||
private:
|
||||
enum kOp
|
||||
{
|
||||
kOpen,
|
||||
kSave
|
||||
};
|
||||
QString fileName_;
|
||||
OstProto::StreamConfigList *openStreams_;
|
||||
OstProto::StreamConfigList saveStreams_;
|
||||
QString *error_;
|
||||
kOp op_;
|
||||
bool result_;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -322,6 +322,8 @@ bool FileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||
goto _zero_cksum_serialize_fail;
|
||||
}
|
||||
|
||||
emit status("Calculating checksum...");
|
||||
|
||||
// Calculate and write checksum
|
||||
calcCksum = checksumCrc32C((quint8*)buf.constData(), buf.size());
|
||||
cksum.set_value(calcCksum);
|
||||
@ -335,6 +337,7 @@ bool FileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||
qDebug("Writing %d bytes", buf.size());
|
||||
//qDebug("%s", QString(buf.toHex()).toAscii().constData());
|
||||
|
||||
emit status("Writing to disk...");
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
goto _open_fail;
|
||||
|
||||
|
@ -64,7 +64,7 @@ PcapFileFormat::~PcapFileFormat()
|
||||
bool PcapFileFormat::openStreams(const QString fileName,
|
||||
OstProto::StreamConfigList &streams, QString &error)
|
||||
{
|
||||
bool viaPdml = true; // TODO: shd be a param to function
|
||||
bool viaPdml = false; // TODO: shd be a param to function
|
||||
|
||||
bool isOk = false;
|
||||
QFile file(fileName);
|
||||
@ -77,6 +77,8 @@ bool PcapFileFormat::openStreams(const QString fileName,
|
||||
OstProto::Stream *prevStream = NULL;
|
||||
uint lastUsec = 0;
|
||||
int pktCount;
|
||||
qint64 byteCount = 0;
|
||||
qint64 byteTotal;
|
||||
QByteArray pktBuf;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
@ -90,6 +92,9 @@ bool PcapFileFormat::openStreams(const QString fileName,
|
||||
{
|
||||
QProcess gzip;
|
||||
|
||||
emit status("Decompressing...");
|
||||
emit target(0);
|
||||
|
||||
if (!file2.open())
|
||||
{
|
||||
error.append("Unable to open temporary file to uncompress .gz\n");
|
||||
@ -126,6 +131,11 @@ bool PcapFileFormat::openStreams(const QString fileName,
|
||||
fd_.setDevice(&file);
|
||||
}
|
||||
|
||||
byteTotal = fd_.device()->size() - sizeof(fileHdr);
|
||||
|
||||
emit status("Reading File Header...");
|
||||
emit target(0);
|
||||
|
||||
fd_ >> magic;
|
||||
|
||||
qDebug("magic = %08x", magic);
|
||||
@ -173,6 +183,8 @@ bool PcapFileFormat::openStreams(const QString fileName,
|
||||
}
|
||||
|
||||
qDebug("generating PDML %s", pdmlFile.fileName().toAscii().constData());
|
||||
emit status("Generating PDML...");
|
||||
emit target(0);
|
||||
|
||||
tshark.setStandardOutputFile(pdmlFile.fileName());
|
||||
// FIXME: hardcoded prog name
|
||||
@ -193,12 +205,18 @@ bool PcapFileFormat::openStreams(const QString fileName,
|
||||
goto _non_pdml;
|
||||
}
|
||||
|
||||
isOk = reader.read(&pdmlFile, this); // TODO: pass error string?
|
||||
connect(&reader, SIGNAL(progress(int)), this, SIGNAL(progress(int)));
|
||||
|
||||
emit status("Reading PDML packets...");
|
||||
emit target(100); // in percentage
|
||||
isOk = reader.read(&pdmlFile, this, &stop_); // TODO: pass error string?
|
||||
goto _exit;
|
||||
|
||||
}
|
||||
|
||||
_non_pdml:
|
||||
emit status("Reading Packets...");
|
||||
emit target(100); // in percentage
|
||||
pktCount = 1;
|
||||
while (!fd_.atEnd())
|
||||
{
|
||||
@ -235,11 +253,20 @@ _non_pdml:
|
||||
lastUsec = usec;
|
||||
prevStream = stream;
|
||||
pktCount++;
|
||||
qDebug("pktCount = %d", pktCount);
|
||||
byteCount += pktHdr.inclLen + sizeof(pktHdr);
|
||||
emit progress(int(byteCount*100/byteTotal)); // in percentage
|
||||
if (stop_)
|
||||
goto _user_cancel;
|
||||
}
|
||||
|
||||
isOk = true;
|
||||
goto _exit;
|
||||
|
||||
_user_cancel:
|
||||
isOk = true;
|
||||
goto _exit;
|
||||
|
||||
#if 1
|
||||
_err_unsupported_encap:
|
||||
error = QString(tr("%1 has non-ethernet encapsulation (%2) which is "
|
||||
@ -344,6 +371,9 @@ bool PcapFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||
|
||||
pktBuf.resize(kMaxSnapLen);
|
||||
|
||||
emit status("Writing Packets...");
|
||||
emit target(streams.stream_size());
|
||||
|
||||
pktHdr.tsSec = 0;
|
||||
pktHdr.tsUsec = 0;
|
||||
for (int i = 0; i < streams.stream_size(); i++)
|
||||
@ -377,6 +407,8 @@ bool PcapFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||
pktHdr.tsSec++;
|
||||
pktHdr.tsUsec -= 1000000;
|
||||
}
|
||||
|
||||
emit progress(i);
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
@ -115,6 +115,8 @@ PdmlReader::PdmlReader(OstProto::StreamConfigList *streams)
|
||||
currentStream_ = NULL;
|
||||
prevStream_ = NULL;
|
||||
|
||||
stop_ = NULL;
|
||||
|
||||
factory_.insert("hexdump", PdmlUnknownProtocol::createInstance);
|
||||
factory_.insert("geninfo", PdmlGenInfoProtocol::createInstance);
|
||||
factory_.insert("frame", PdmlFrameProtocol::createInstance);
|
||||
@ -128,12 +130,13 @@ PdmlReader::~PdmlReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool PdmlReader::read(QIODevice *device, PcapFileFormat *pcap)
|
||||
bool PdmlReader::read(QIODevice *device, PcapFileFormat *pcap, bool *stop)
|
||||
{
|
||||
setDevice(device);
|
||||
pcap_ = pcap;
|
||||
packetCount_ = 0;
|
||||
|
||||
stop_ = stop;
|
||||
while (!atEnd())
|
||||
{
|
||||
readNext();
|
||||
@ -146,7 +149,7 @@ bool PdmlReader::read(QIODevice *device, PcapFileFormat *pcap)
|
||||
}
|
||||
}
|
||||
|
||||
if (error())
|
||||
if (error() && (errorString() != "USER-CANCEL"))
|
||||
{
|
||||
qDebug("Line %lld", lineNumber());
|
||||
qDebug("Col %lld", columnNumber());
|
||||
@ -325,8 +328,11 @@ void PdmlReader::readPacket()
|
||||
}
|
||||
|
||||
packetCount_++;
|
||||
emit progress(int(characterOffset()*100/device()->size()));
|
||||
if (prevStream_)
|
||||
prevStream_->mutable_control()->CopyFrom(currentStream_->control());
|
||||
if (stop_ && *stop_)
|
||||
raiseError("USER-CANCEL");
|
||||
}
|
||||
|
||||
void PdmlReader::readProto()
|
||||
|
@ -62,14 +62,18 @@ protected:
|
||||
|
||||
class PdmlUnknownProtocol;
|
||||
class PcapFileFormat;
|
||||
class PdmlReader : public QXmlStreamReader
|
||||
class PdmlReader : public QObject, public QXmlStreamReader
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class PdmlUnknownProtocol;
|
||||
public:
|
||||
PdmlReader(OstProto::StreamConfigList *streams);
|
||||
~PdmlReader();
|
||||
|
||||
bool read(QIODevice *device, PcapFileFormat *pcap = NULL);
|
||||
bool read(QIODevice *device, PcapFileFormat *pcap = NULL,
|
||||
bool *stop = NULL);
|
||||
signals:
|
||||
void progress(int value);
|
||||
|
||||
private:
|
||||
PdmlDefaultProtocol* allocPdmlProtocol(QString protoName);
|
||||
@ -103,6 +107,7 @@ private:
|
||||
OstProto::Stream *currentStream_;
|
||||
|
||||
QByteArray pktBuf_;
|
||||
bool *stop_;
|
||||
};
|
||||
|
||||
class PdmlUnknownProtocol : public PdmlDefaultProtocol
|
||||
|
@ -30,39 +30,6 @@ PdmlFileFormat::~PdmlFileFormat()
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool PdmlFileFormat::openStreams(const QString fileName,
|
||||
OstProto::StreamConfigList &streams, QString &error)
|
||||
{
|
||||
bool isOk;
|
||||
QFile file(fileName);
|
||||
PdmlParser *pdml;
|
||||
QXmlSimpleReader *xmlReader;
|
||||
QXmlInputSource *xmlSource;
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
goto _open_fail;
|
||||
|
||||
pdml = new PdmlParser(&streams);
|
||||
xmlSource = new QXmlInputSource(&file);
|
||||
xmlReader = new QXmlSimpleReader;
|
||||
xmlReader->setContentHandler(pdml);
|
||||
xmlReader->setErrorHandler(pdml);
|
||||
isOk = xmlReader->parse(xmlSource, false); // non-incremental parse
|
||||
|
||||
goto _exit;
|
||||
|
||||
_open_fail:
|
||||
isOk = false;
|
||||
|
||||
_exit:
|
||||
delete xmlReader;
|
||||
delete xmlSource;
|
||||
delete pdml;
|
||||
|
||||
return isOk;
|
||||
}
|
||||
#else
|
||||
bool PdmlFileFormat::openStreams(const QString fileName,
|
||||
OstProto::StreamConfigList &streams, QString &error)
|
||||
{
|
||||
@ -73,6 +40,10 @@ bool PdmlFileFormat::openStreams(const QString fileName,
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
goto _open_fail;
|
||||
|
||||
connect(reader, SIGNAL(progress(int)), this, SIGNAL(progress(int)));
|
||||
emit status("Reading PDML packets...");
|
||||
emit target(100); // in percentage
|
||||
|
||||
// TODO: fill in error string
|
||||
|
||||
isOk = reader->read(&file);
|
||||
@ -87,7 +58,6 @@ _exit:
|
||||
|
||||
return isOk;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool PdmlFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||
const QString fileName, QString &error)
|
||||
|
Loading…
Reference in New Issue
Block a user