Refactored FileFormat Classes with an Abstract base class. Open/Save streams enhanced to support the new file formats - PCAP and PDML

This commit is contained in:
Srivats P. 2011-03-13 22:36:33 +05:30
parent ed03f06f44
commit 69d488d8a2
12 changed files with 284 additions and 40 deletions

View File

@ -19,9 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "port.h"
#include "fileformat.h"
#include "pcapfileformat.h"
#include "pdmlfileformat.h"
#include "abstractfileformat.h"
#include <QApplication>
#include <QVariant>
@ -228,10 +226,12 @@ void Port::updateStats(OstProto::PortStats *portStats)
bool Port::openStreams(QString fileName, bool append, QString &error)
{
OstProto::StreamConfigList streams;
AbstractFileFormat *fmt = AbstractFileFormat::fileFormatFromFile(fileName);
//if (!fileFormat.openStreams(fileName, streams, error))
//if (!pdmlFileFormat.openStreams(fileName, streams, error))
if (!pcapFileFormat.openStreams(fileName, streams, error))
if (fmt == NULL)
goto _fail;
if (!fmt->openStreams(fileName, streams, error))
goto _fail;
if (!append)
@ -253,10 +253,14 @@ _fail:
return false;
}
bool Port::saveStreams(QString fileName, QString &error)
bool Port::saveStreams(QString fileName, QString fileType, QString &error)
{
AbstractFileFormat *fmt = AbstractFileFormat::fileFormatFromType(fileType);
OstProto::StreamConfigList streams;
if (fmt == NULL)
goto _fail;
streams.mutable_port_id()->set_id(0);
for (int i = 0; i < mStreams.size(); i++)
{
@ -264,6 +268,9 @@ bool Port::saveStreams(QString fileName, QString &error)
mStreams[i]->protoDataCopyInto(*s);
}
//return fileFormat.saveStreams(streams, fileName, error);
return pcapFileFormat.saveStreams(streams, fileName, error);
return fmt->saveStreams(streams, fileName, error);
_fail:
error = QString("Unsupported File Type - %1").arg(fileType);
return false;
}

View File

@ -119,7 +119,7 @@ public:
void updateStats(OstProto::PortStats *portStats);
bool openStreams(QString fileName, bool append, QString &error);
bool saveStreams(QString fileName, QString &error);
bool saveStreams(QString fileName, QString fileType, QString &error);
signals:
void portDataChanged(int portGroupId, int portId);

View File

@ -19,13 +19,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "portswindow.h"
#include "abstractfileformat.h"
#include "streamconfigdialog.h"
#include "streamlistdelegate.h"
#include <QInputDialog>
#include <QItemSelectionModel>
#include <QMessageBox>
#include "streamconfigdialog.h"
#include "streamlistdelegate.h"
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
: QWidget(parent)
{
@ -497,17 +498,44 @@ void PortsWindow::on_actionSave_Streams_triggered()
QModelIndex current = tvPortList->selectionModel()->currentIndex();
QString fileName;
QStringList fileTypes = AbstractFileFormat::supportedFileTypes();
QString fileType;
QString errorStr;
QFileDialog::Options options;
// On Mac OS with Native Dialog, getSaveFileName() ignores fileType
// which we need.
#ifdef Q_OS_MAC
options |= QFileDialog::DontUseNativeDialog;
#endif
if (fileTypes.size())
fileType = fileTypes.at(0);
Q_ASSERT(plm->isPort(current));
fileName = QFileDialog::getSaveFileName(this, tr("Save Streams"));
_retry:
fileName = QFileDialog::getSaveFileName(this, tr("Save Streams"),
fileName, fileTypes.join(";;"), &fileType, options);
if (fileName.isEmpty())
goto _exit;
fileType = fileType.remove(QRegExp("\\(.*\\)")).trimmed();
if (!fileType.startsWith("Ostinato"))
{
if (QMessageBox::warning(this, tr("Ostinato"),
QString("You have chosen to save in %1 format. All stream "
"attributes may not be saved in this format.\n\n"
"It is recommended to save in native Ostinato format.\n\n"
"Continue to save in %2 format?").arg(fileType).arg(fileType),
QMessageBox::Yes|QMessageBox::No,
QMessageBox::No) != QMessageBox::Yes)
goto _retry;
}
// TODO: all or selected?
if (!plm->port(current).saveStreams(fileName, errorStr))
if (!plm->port(current).saveStreams(fileName, fileType, errorStr))
QMessageBox::critical(this, qApp->applicationName(), errorStr);
else if (!errorStr.isEmpty())
QMessageBox::warning(this, qApp->applicationName(), errorStr);

View File

@ -0,0 +1,73 @@
/*
Copyright (C) 2011 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "abstractfileformat.h"
#include "fileformat.h"
#include "pcapfileformat.h"
#include "pdmlfileformat.h"
#include <QStringList>
AbstractFileFormat::AbstractFileFormat()
{
}
AbstractFileFormat::~AbstractFileFormat()
{
}
QStringList AbstractFileFormat::supportedFileTypes()
{
return QStringList()
<< "Ostinato (*)"
<< "PCAP (*)"
<< "PDML (*.pdml)";
}
AbstractFileFormat* AbstractFileFormat::fileFormatFromFile(
const QString fileName)
{
if (fileFormat.isMyFileFormat(fileName))
return &fileFormat;
if (pdmlFileFormat.isMyFileFormat(fileName))
return &pdmlFileFormat;
if (pcapFileFormat.isMyFileFormat(fileName))
return &pcapFileFormat;
return NULL;
}
AbstractFileFormat* AbstractFileFormat::fileFormatFromType(
const QString fileType)
{
if (fileFormat.isMyFileType(fileType))
return &fileFormat;
if (pdmlFileFormat.isMyFileType(fileType))
return &pdmlFileFormat;
if (pcapFileFormat.isMyFileType(fileType))
return &pcapFileFormat;
return NULL;
}

View File

@ -0,0 +1,52 @@
/*
Copyright (C) 2011 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _ABSTRACT_FILE_FORMAT_H
#define _ABSTRACT_FILE_FORMAT_H
#include "protocol.pb.h"
#include <QObject>
#include <QString>
class AbstractFileFormat : public QObject
{
Q_OBJECT
public:
AbstractFileFormat();
virtual ~AbstractFileFormat();
virtual bool openStreams(const QString fileName,
OstProto::StreamConfigList &streams, QString &error) = 0;
virtual bool saveStreams(const OstProto::StreamConfigList streams,
const QString fileName, QString &error) = 0;
static AbstractFileFormat* fileFormatFromFile(const QString fileName);
static AbstractFileFormat* fileFormatFromType(const QString fileType);
static QStringList supportedFileTypes();
#if 0
bool isMyFileFormat(const QString fileName) = 0;
bool isMyFileType(const QString fileType) = 0;
#endif
};
#endif

View File

@ -394,6 +394,38 @@ _fail:
return false;
}
bool FileFormat::isMyFileFormat(const QString fileName)
{
bool ret = false;
QFile file(fileName);
QByteArray buf;
OstProto::FileMagic magic;
if (!file.open(QIODevice::ReadOnly))
goto _exit;
buf = file.peek(kFileMagicOffset + kFileMagicSize);
if (!magic.ParseFromArray((void*)(buf.constData() + kFileMagicOffset),
kFileMagicSize))
goto _close_exit;
if (magic.value() == kFileMagicValue)
ret = true;
_close_exit:
file.close();
_exit:
return ret;
}
bool FileFormat::isMyFileType(const QString fileType)
{
if (fileType.startsWith("Ostinato"))
return true;
else
return false;
}
void FileFormat::initFileMetaData(OstProto::FileMetaData &metaData)
{
// Fill in the "native" file format version

View File

@ -19,24 +19,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _FILE_FORMAT_H
#define _FILE_FORMAT_H
#include "abstractfileformat.h"
#include "fileformat.pb.h"
#include <QString>
#include <QObject>
class FileFormat : public QObject
class FileFormat : public AbstractFileFormat
{
Q_OBJECT
public:
FileFormat();
~FileFormat();
bool openStreams(const QString fileName,
virtual bool openStreams(const QString fileName,
OstProto::StreamConfigList &streams, QString &error);
bool saveStreams(const OstProto::StreamConfigList streams,
virtual bool saveStreams(const OstProto::StreamConfigList streams,
const QString fileName, QString &error);
bool isMyFileFormat(const QString fileName);
bool isMyFileType(const QString fileType);
private:
void initFileMetaData(OstProto::FileMetaData &metaData);
static const int kFileMagicSize = 12;
static const int kFileChecksumSize = 5;
static const int kFileMinSize = kFileMagicSize + kFileChecksumSize;
@ -50,8 +53,6 @@ private:
static const uint kFileFormatVersionMajor = 0;
static const uint kFileFormatVersionMinor = 1;
static const uint kFileFormatVersionRevision = 3;
void initFileMetaData(OstProto::FileMetaData &metaData);
};
extern FileFormat fileFormat;

View File

@ -57,6 +57,7 @@ PROTOS += \
HEADERS += \
abstractprotocol.h \
comboprotocol.h \
abstractfileformat.h \
fileformat.h \
pcapfileformat.h \
pdmlfileformat.h \
@ -98,6 +99,7 @@ HEADERS += \
SOURCES += \
abstractprotocol.cpp \
crc32c.cpp \
abstractfileformat.cpp \
fileformat.cpp \
pcapfileformat.cpp \
pdmlfileformat.cpp \

View File

@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include <QDataStream>
#include <QFile>
#include <QFileInfo>
#include <QProcess>
#include <QTemporaryFile>
#include <QtGlobal>
@ -243,7 +244,7 @@ _non_pdml:
_err_unsupported_encap:
error = QString(tr("%1 has non-ethernet encapsulation (%2) which is "
"not supported - Sorry!"))
.arg(fileName).arg(fileHdr.network);
.arg(QFileInfo(fileName).fileName()).arg(fileHdr.network);
goto _exit;
#endif
@ -391,3 +392,16 @@ _exit:
return isOk;
}
bool PcapFileFormat::isMyFileFormat(const QString fileName)
{
// TODO
return true;
}
bool PcapFileFormat::isMyFileType(const QString fileType)
{
if (fileType.startsWith("PCAP"))
return true;
else
return false;
}

View File

@ -19,16 +19,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _PCAP_FILE_FORMAT_H
#define _PCAP_FILE_FORMAT_H
#include "protocol.pb.h"
#include "abstractfileformat.h"
#include <QDataStream>
#include <QObject>
class PdmlReader;
class PcapFileFormat : public QObject
class PcapFileFormat : public AbstractFileFormat
{
Q_OBJECT
friend class PdmlReader;
public:
@ -40,6 +37,9 @@ public:
bool saveStreams(const OstProto::StreamConfigList streams,
const QString fileName, QString &error);
bool isMyFileFormat(const QString fileName);
bool isMyFileType(const QString fileType);
private:
typedef struct {
quint32 magicNumber; /* magic number */

View File

@ -92,6 +92,43 @@ _exit:
bool PdmlFileFormat::saveStreams(const OstProto::StreamConfigList streams,
const QString fileName, QString &error)
{
error = "Save to PDML format is not supported";
return false;
}
bool PdmlFileFormat::isMyFileFormat(const QString fileName)
{
bool ret = false;
QFile file(fileName);
QByteArray buf;
QXmlStreamReader xml;
if (!file.open(QIODevice::ReadOnly))
goto _exit;
xml.setDevice(&file);
xml.readNext();
if (xml.hasError() || !xml.isStartDocument())
goto _close_exit;
xml.readNext();
if (!xml.hasError() && xml.isStartElement() && (xml.name() == "pdml"))
ret = true;
else
ret = false;
_close_exit:
xml.clear();
file.close();
_exit:
return ret;
}
bool PdmlFileFormat::isMyFileType(const QString fileType)
{
if (fileType.startsWith("PDML"))
return true;
else
return false;
}

View File

@ -19,24 +19,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _PDML_FILE_FORMAT_H
#define _PDML_FILE_FORMAT_H
#include "protocol.pb.h"
#include "abstractfileformat.h"
#include <QObject>
class PdmlParser;
class PdmlFileFormat : public QObject
class PdmlFileFormat : public AbstractFileFormat
{
Q_OBJECT
public:
PdmlFileFormat();
~PdmlFileFormat();
bool openStreams(const QString fileName,
virtual bool openStreams(const QString fileName,
OstProto::StreamConfigList &streams, QString &error);
bool saveStreams(const OstProto::StreamConfigList streams,
virtual bool saveStreams(const OstProto::StreamConfigList streams,
const QString fileName, QString &error);
bool isMyFileFormat(const QString fileName);
bool isMyFileType(const QString fileType);
};
extern PdmlFileFormat pdmlFileFormat;