Open/Save Progress Dialog done

This commit is contained in:
Srivats P. 2011-03-17 22:00:51 +05:30
parent 1e805661fc
commit 00e03a44fd
9 changed files with 237 additions and 53 deletions

View File

@ -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;
}

View File

@ -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"),

View File

@ -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_);
}

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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()

View File

@ -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

View File

@ -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)