Added, edited, corrected and completed the AbstractProtocol doxygen documentation
This commit is contained in:
parent
0075a3712b
commit
ae05037265
@ -26,20 +26,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
/*!
|
||||
\class AbstractProtocol
|
||||
|
||||
\todo (MED) update AbstractProtocol documentation
|
||||
Bare Minimum set of methods that a subclass needs to reimplement
|
||||
AbstractProtocol is the base abstract class which provides the interface
|
||||
for all protocols.
|
||||
|
||||
All protocols supported by Ostinato are derived from AbstractProtocol. Apart
|
||||
from defining the interface for a protocol, it also provides sensible default
|
||||
implementations for methods so that the subclasses need not re-implement. It
|
||||
also provides convenience functions for subclasses to use such as methods to
|
||||
retrieve payload size, checksum etc.
|
||||
|
||||
A subclass typically needs to reimplement the following methods -
|
||||
- name()
|
||||
- shortName()
|
||||
- createInstance()
|
||||
- protocolNumber()
|
||||
- protoDataCopyInto() [pure virtual]
|
||||
- protoDataCopyFrom() [pure virtual]
|
||||
- fieldCount()
|
||||
- fieldFlags()
|
||||
- fieldData()
|
||||
- setFieldData()
|
||||
- configWidget() [pure virtual]
|
||||
- loadConfigWidget() [pure virtual]
|
||||
- storeConfigWidget() [pure virtual]
|
||||
|
||||
Any useful protocol should also provide implementations for
|
||||
- name()
|
||||
- shortName()
|
||||
- fieldName()
|
||||
Depending on certain conditions, subclasses may need to reimplement the
|
||||
following additional methods -
|
||||
- protocolIdType()
|
||||
- protocolId()
|
||||
- protocolFrameSize()
|
||||
- isProtocolFrameValueVariable()
|
||||
- isProtocolFrameSizeVariable()
|
||||
|
||||
Protocols with meta fields should additionally implement
|
||||
- metaFieldCount()
|
||||
- isMetaField()
|
||||
See the description of the methods for more information.
|
||||
|
||||
Most of the above methods just need some standard boilerplate code -
|
||||
the SampleProtocol implementation includes the boilerplate
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an abstract protocol for the given stream and parent
|
||||
|
||||
parent is typically NULL except for protocols which are part of a
|
||||
ComboProtocol
|
||||
*/
|
||||
AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
{
|
||||
@ -51,16 +80,31 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
protoSize = -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the abstract protocol
|
||||
*/
|
||||
AbstractProtocol::~AbstractProtocol()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Allocates and returns a new instance of the class.
|
||||
|
||||
Caller is responsible for freeing up after use. Subclasses MUST implement
|
||||
this function
|
||||
*/
|
||||
AbstractProtocol* AbstractProtocol::createInstance(StreamBase* /* stream */,
|
||||
AbstractProtocol* /* parent */)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the protocol's field number as defined in message 'Protocol', enum 'k'
|
||||
(file: protocol.proto)
|
||||
|
||||
Subclasses MUST implement this function
|
||||
*/
|
||||
quint32 AbstractProtocol::protocolNumber() const
|
||||
{
|
||||
qFatal("Something wrong!!!");
|
||||
@ -68,29 +112,44 @@ quint32 AbstractProtocol::protocolNumber() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn virtual void protoDataCopyInto(OstProto::OstProto::StreamCore &stream) = 0;
|
||||
\fn virtual void AbstractProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const = 0
|
||||
|
||||
Copy the protocol's protobuf into the passed in stream \n
|
||||
In the base class this is a pure virtual function. Subclasses should
|
||||
implement this function by using - \n
|
||||
stream.AddExtension(<ExtId>)->CopyFrom(<protobuf_data>) */
|
||||
Copy the protocol's protobuf as an extension into the passed in protocol
|
||||
|
||||
/*
|
||||
\fn virtual void protoDataCopyFrom(const OstProto::OstProto::StreamCore &stream) = 0;
|
||||
*/
|
||||
In the base class this is a pure virtual function. Subclasses MUST implement
|
||||
this function. See the SampleProtocol for an example
|
||||
*/
|
||||
|
||||
/*! Returns the full name of the protocol \n
|
||||
The default implementation returns a null string */
|
||||
|
||||
/*!
|
||||
\fn virtual void AbstractProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) = 0
|
||||
|
||||
Copy and update the protocol's protobuf member data variable from the
|
||||
passed in protocol
|
||||
|
||||
In the base class this is a pure virtual function. Subclasses MUST implement
|
||||
this function. See the SampleProtocol for an example
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
Returns the full name of the protocol
|
||||
|
||||
The default implementation returns a null string
|
||||
*/
|
||||
QString AbstractProtocol::name() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
/*! Returns the short name or abbreviation of the protocol \n
|
||||
The default implementation forms and returns a abbreviation composed
|
||||
/*!
|
||||
Returns the short name or abbreviation of the protocol
|
||||
|
||||
The default implementation forms and returns an abbreviation composed
|
||||
of all the upper case chars in name() \n
|
||||
The default implementation caches the abbreviation on its first invocation
|
||||
and subsequently returns the cached abbreviation */
|
||||
and subsequently returns the cached abbreviation
|
||||
*/
|
||||
QString AbstractProtocol::shortName() const
|
||||
{
|
||||
if (protoAbbr.isNull())
|
||||
@ -109,19 +168,27 @@ QString AbstractProtocol::shortName() const
|
||||
return protoAbbr;
|
||||
}
|
||||
|
||||
/*! Returns the number of fields (both Frame and Meta fields) \n
|
||||
The default implementation returns zero */
|
||||
int AbstractProtocol::fieldCount() const
|
||||
/*!
|
||||
Returns the number of fields in the protocol (both Frame fields and
|
||||
Meta fields)
|
||||
|
||||
The default implementation returns zero. Subclasses MUST implement this
|
||||
function.
|
||||
*/
|
||||
int AbstractProtocol::fieldCount() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Returns the number of meta fields \n
|
||||
/*!
|
||||
Returns the number of meta fields
|
||||
|
||||
The default implementation counts and returns the number of fields for which
|
||||
the FieldIsMeta flag is set\n
|
||||
The default implementation caches the count on its first invocation
|
||||
and subsequently returns the cached count */
|
||||
int AbstractProtocol::metaFieldCount() const
|
||||
and subsequently returns the cached count
|
||||
*/
|
||||
int AbstractProtocol::metaFieldCount() const
|
||||
{
|
||||
if (metaCount < 0)
|
||||
{
|
||||
@ -135,24 +202,35 @@ int AbstractProtocol::metaFieldCount() const
|
||||
return metaCount;
|
||||
}
|
||||
|
||||
/*! Returns the number of frame fields \n
|
||||
Convenience method - same as fieldCount() minus metaFieldCount() */
|
||||
int AbstractProtocol::frameFieldCount() const
|
||||
/*!
|
||||
Returns the number of frame fields
|
||||
|
||||
Convenience method - same as fieldCount() minus metaFieldCount()
|
||||
*/
|
||||
int AbstractProtocol::frameFieldCount() const
|
||||
{
|
||||
//qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount());
|
||||
return (fieldCount() - metaFieldCount());
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the field flags for the passed in field index
|
||||
|
||||
The default implementation assumes all fields to be frame fields and returns
|
||||
'FieldIsNormal'. Subclasses must reimplement this method if they have any
|
||||
meta fields or checksum fields. See the SampleProtocol for an example.
|
||||
*/
|
||||
AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const
|
||||
{
|
||||
return FieldIsNormal;
|
||||
}
|
||||
|
||||
/*! Returns the requested field attribute data \n
|
||||
/*!
|
||||
Returns the requested field attribute data
|
||||
|
||||
Protocols which have meta fields that vary a frame field across
|
||||
streams may use the streamIndex to return the appropriate field value \n
|
||||
Some field attriubutes e.g. FieldName may be invariant across streams\n
|
||||
The default implementation returns the fieldValue() converted to string
|
||||
Some field attributes e.g. FieldName may be invariant across streams\n
|
||||
The FieldTextValue attribute may include additional information about
|
||||
the field's value e.g. a checksum field may include "(correct)" or
|
||||
"(incorrect)" alongwith the actual checksum value. \n
|
||||
@ -167,14 +245,14 @@ AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const
|
||||
fields whose size are a non-integral multiple of bytes or smaller than
|
||||
a byte, subclasses should return the correct value. Also for fields
|
||||
which represent checksums, subclasses should return a value for
|
||||
FieldBitSize - even if it is an integral multiple of bytes
|
||||
FieldBitSize - even if it is an integral multiple of bytes.
|
||||
|
||||
\note If a subclass uses any of the below functions to derive
|
||||
FieldFrameValue, the subclass should handle and return a value for
|
||||
FieldBitSize to prevent endless recrusion -
|
||||
- protocolFrameCksum()
|
||||
- protocolFramePayloadSize()
|
||||
*/
|
||||
*/
|
||||
QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib,
|
||||
int streamIndex) const
|
||||
{
|
||||
@ -203,25 +281,58 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib,
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
/*! Sets the value of a field corresponding to index \n
|
||||
Returns true if field is successfully set, false otherwise \n
|
||||
The default implementation always returns false */
|
||||
/*!
|
||||
Sets the value of a field corresponding to index
|
||||
|
||||
This method is called by the GUI code to store a user specified value into
|
||||
the protocol's protoBuf. Currently this method is called with
|
||||
FieldAttrib = FieldValue only.
|
||||
|
||||
Returns true if field is successfully set, false otherwise.
|
||||
The default implementation always returns false. Subclasses should
|
||||
reimplement this method. See SampleProtocol for an example.
|
||||
|
||||
*/
|
||||
bool AbstractProtocol::setFieldData(int /*index*/, const QVariant& /*value*/,
|
||||
FieldAttrib /*attrib*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the protocolIdType for the protocol
|
||||
|
||||
The default implementation returns ProtocolIdNone. If a subclass has a
|
||||
protocolId field it should return the appropriate value e.g. IP protocol
|
||||
will return ProtocolIdIp, Ethernet will return ProtocolIdEth etc.
|
||||
*/
|
||||
AbstractProtocol::ProtocolIdType AbstractProtocol::protocolIdType() const
|
||||
{
|
||||
return ProtocolIdNone;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the protocol id of the protocol for the given type
|
||||
|
||||
The default implementation returns 0. If a subclass represents a protocol
|
||||
which has a particular protocol id, it should return the appropriate value.
|
||||
If a protocol does not have an id for the given type, it should defer to
|
||||
the base class. e.g. IGMP will return 2 for ProtocolIdIp, and defer to the
|
||||
base class for the remaining ProtocolIdTypes; IP will return 0x800 for
|
||||
ProtocolIdEth type, 0x060603 for ProtocolIdLlc and 0x04 for ProtocolIdIp etc.
|
||||
*/
|
||||
quint32 AbstractProtocol::protocolId(ProtocolIdType /*type*/) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the protocol id of the payload protocol (the protocol that
|
||||
immediately follows the current one)
|
||||
|
||||
A subclass which has a protocol id field, can use this to retrieve the
|
||||
appropriate value
|
||||
*/
|
||||
quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const
|
||||
{
|
||||
quint32 id;
|
||||
@ -237,6 +348,16 @@ quint32 AbstractProtocol::payloadProtocolId(ProtocolIdType type) const
|
||||
return id;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the protocol's size in bytes
|
||||
|
||||
The default implementation sums up the individual field bit sizes and
|
||||
returns it. The default implementation calculates the caches the size on
|
||||
the first invocation and subsequently returns the cached size.
|
||||
|
||||
If the subclass protocol has a varying protocol size, it MUST reimplement
|
||||
this method, otherwise the default implementation is sufficient.
|
||||
*/
|
||||
int AbstractProtocol::protocolFrameSize(int streamIndex) const
|
||||
{
|
||||
if (protoSize < 0)
|
||||
@ -255,6 +376,13 @@ int AbstractProtocol::protocolFrameSize(int streamIndex) const
|
||||
return protoSize;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the byte offset in the packet where the protocol starts
|
||||
|
||||
This method is useful only for "padding" protocols i.e. protocols which
|
||||
fill up the remaining space for the user defined packet size e.g. the
|
||||
PatternPayload protocol
|
||||
*/
|
||||
int AbstractProtocol::protocolFrameOffset(int streamIndex) const
|
||||
{
|
||||
int size = 0;
|
||||
@ -272,6 +400,12 @@ int AbstractProtocol::protocolFrameOffset(int streamIndex) const
|
||||
return size;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the size of the payload in bytes. The payload includes all protocols
|
||||
subsequent to the current
|
||||
|
||||
This method is useful for protocols which need to fill in a payload size field
|
||||
*/
|
||||
int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const
|
||||
{
|
||||
int size = 0;
|
||||
@ -289,11 +423,14 @@ int AbstractProtocol::protocolFramePayloadSize(int streamIndex) const
|
||||
}
|
||||
|
||||
|
||||
/*! Returns a byte array encoding the protocol (and its fields) which can be
|
||||
/*!
|
||||
Returns a byte array encoding the protocol (and its fields) which can be
|
||||
inserted into the stream's frame
|
||||
|
||||
The default implementation forms and returns an ordered concatenation of
|
||||
the FrameValue of all the 'frame' fields of the protocol taking care of fields
|
||||
which are not an integral number of bytes\n */
|
||||
the FrameValue of all the 'frame' fields of the protocol also taking care of
|
||||
fields which are not an integral number of bytes\n
|
||||
*/
|
||||
QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum) const
|
||||
{
|
||||
QByteArray proto, field;
|
||||
@ -386,16 +523,38 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum)
|
||||
return proto;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the protocol varies one or more of its fields at run-time,
|
||||
false otherwise
|
||||
|
||||
The default implementation returns false. A subclass should reimplement
|
||||
if it has varying fields e.g. an IP protocol that increments/decrements
|
||||
the IP address with every packet
|
||||
*/
|
||||
bool AbstractProtocol::isProtocolFrameValueVariable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the protocol varies its size at run-time, false otherwise
|
||||
|
||||
The default implmentation returns false. A subclass should reimplement
|
||||
if it varies its size at run-time e.g. a Payload protocol for a stream with
|
||||
incrementing/decrementing frame lengths
|
||||
*/
|
||||
bool AbstractProtocol::isProtocolFrameSizeVariable() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the payload content for a protocol varies at run-time,
|
||||
false otherwise
|
||||
|
||||
This is useful for subclasses which have fields dependent on payload content
|
||||
(e.g. UDP has a checksum field that varies if the payload varies)
|
||||
*/
|
||||
bool AbstractProtocol::isProtocolFramePayloadValueVariable() const
|
||||
{
|
||||
AbstractProtocol *p = next;
|
||||
@ -412,6 +571,13 @@ bool AbstractProtocol::isProtocolFramePayloadValueVariable() const
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the payload size for a protocol varies at run-time,
|
||||
false otherwise
|
||||
|
||||
This is useful for subclasses which have fields dependent on payload size
|
||||
(e.g. UDP has a checksum field that varies if the payload varies)
|
||||
*/
|
||||
bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const
|
||||
{
|
||||
AbstractProtocol *p = next;
|
||||
@ -428,14 +594,17 @@ bool AbstractProtocol::isProtocolFramePayloadSizeVariable() const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the checksum (of the requested type) of the protocol's contents
|
||||
|
||||
Useful for protocols which have a checksum field
|
||||
|
||||
\note If a subclass uses protocolFrameCksum() from within fieldData() to
|
||||
derive a cksum field, it MUST handle and return the 'FieldBitSize'
|
||||
attribute also for that particular field instead of using the default
|
||||
AbstractProtocol implementation for 'FieldBitSize' - this is required
|
||||
to prevent infinite recursion
|
||||
*/
|
||||
*/
|
||||
quint32 AbstractProtocol::protocolFrameCksum(int streamIndex,
|
||||
CksumType cksumType) const
|
||||
{
|
||||
@ -502,6 +671,14 @@ quint32 AbstractProtocol::protocolFrameCksum(int streamIndex,
|
||||
return cksum;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the checksum of the requested type for the protocol's header
|
||||
|
||||
This is useful for subclasses which needs the header's checksum e.g. TCP/UDP
|
||||
require a "Pseudo-IP" checksum
|
||||
|
||||
Currently the default implementation supports only type CksumIpPseudo
|
||||
*/
|
||||
quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex,
|
||||
CksumType cksumType) const
|
||||
{
|
||||
@ -530,6 +707,15 @@ quint32 AbstractProtocol::protocolFrameHeaderCksum(int streamIndex,
|
||||
return (quint16) ~sum;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the checksum of the requested type for the protocol's payload
|
||||
|
||||
This is useful for subclasses which needs the payload's checksum e.g. TCP/UDP
|
||||
require a IP checksum of the payload (to be combined with other checksums to
|
||||
derive the final checksum)
|
||||
|
||||
Currently the default implementation supports only type CksumIp
|
||||
*/
|
||||
quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex,
|
||||
CksumType cksumType) const
|
||||
{
|
||||
@ -558,3 +744,33 @@ quint32 AbstractProtocol::protocolFramePayloadCksum(int streamIndex,
|
||||
return (quint16) ~sum;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn virtual QWidget* AbstractProtocol::configWidget() = 0;
|
||||
|
||||
Returns the configuration widget for the protocol. The protocol retains
|
||||
ownership of the configuration widget - the caller should not free it.
|
||||
|
||||
In the base class this is a pure virtual function. Subclasses MUST implement
|
||||
this function. See the SampleProtocol for an example
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn virtual void AbstractProtocol::loadConfigWidget() = 0;
|
||||
|
||||
Loads data from the protocol's protobuf into the configuration widget of
|
||||
the protocol
|
||||
|
||||
In the base class this is a pure virtual function. Subclasses MUST implement
|
||||
this function. See the SampleProtocol for an example
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn virtual void AbstractProtocol::storeConfigWidget() = 0;
|
||||
|
||||
Stores data from the configuration widget of the protocol into the protocol's
|
||||
protobuf
|
||||
|
||||
In the base class this is a pure virtual function. Subclasses MUST implement
|
||||
this function. See the SampleProtocol for an example
|
||||
*/
|
||||
|
||||
|
@ -48,45 +48,49 @@ class AbstractProtocol
|
||||
friend class ProtocolListIterator;
|
||||
|
||||
private:
|
||||
mutable int metaCount;
|
||||
mutable int protoSize;
|
||||
mutable int metaCount;
|
||||
mutable int protoSize;
|
||||
mutable QString protoAbbr;
|
||||
|
||||
protected:
|
||||
StreamBase *mpStream;
|
||||
AbstractProtocol *parent;
|
||||
AbstractProtocol *prev;
|
||||
AbstractProtocol *next;
|
||||
StreamBase *mpStream; //!< Stream that this protocol belongs to
|
||||
AbstractProtocol *parent; //!< Parent protocol, if any
|
||||
AbstractProtocol *prev; //!< Protocol preceding this protocol
|
||||
AbstractProtocol *next; //!< Protocol succeeding this protocol
|
||||
|
||||
public:
|
||||
//! Properties of a field, can be OR'd
|
||||
enum FieldFlag {
|
||||
FieldIsNormal = 0x0,
|
||||
FieldIsMeta = 0x1,
|
||||
FieldIsCksum = 0x2
|
||||
FieldIsNormal = 0x0, //!< field appears in frame content
|
||||
FieldIsMeta = 0x1, //!< field does not appear in frame, is meta data
|
||||
FieldIsCksum = 0x2 //!< field is a checksum, appears in frame content
|
||||
};
|
||||
Q_DECLARE_FLAGS(FieldFlags, FieldFlag);
|
||||
Q_DECLARE_FLAGS(FieldFlags, FieldFlag); //!< \private abcd
|
||||
|
||||
//! Various attributes of a field
|
||||
enum FieldAttrib {
|
||||
FieldName, //! name
|
||||
FieldValue, //! value in host byte order (user editable)
|
||||
FieldTextValue, //! value as text
|
||||
FieldFrameValue, //! frame encoded value in network byte order
|
||||
FieldBitSize, //! size in bits
|
||||
FieldName, //!< name
|
||||
FieldValue, //!< value in host byte order (user editable)
|
||||
FieldTextValue, //!< value as text
|
||||
FieldFrameValue, //!< frame encoded value in network byte order
|
||||
FieldBitSize, //!< size in bits
|
||||
};
|
||||
|
||||
//! Supported Protocol Id types
|
||||
enum ProtocolIdType {
|
||||
ProtocolIdNone,
|
||||
ProtocolIdLlc,
|
||||
ProtocolIdEth,
|
||||
ProtocolIdIp,
|
||||
ProtocolIdNone, //!< Marker representing non-existent protocol id
|
||||
ProtocolIdLlc, //!< LLC (802.2)
|
||||
ProtocolIdEth, //!< Ethernet II
|
||||
ProtocolIdIp, //!< IP
|
||||
};
|
||||
|
||||
//! Supported checksum types
|
||||
enum CksumType {
|
||||
CksumIp,
|
||||
CksumIpPseudo,
|
||||
CksumTcpUdp,
|
||||
CksumIp, //!< Standard IP Checksum
|
||||
CksumIpPseudo, //!< Standard checksum for Pseudo-IP header
|
||||
CksumTcpUdp, //!< Standard TCP/UDP checksum including pseudo-IP
|
||||
|
||||
CksumMax
|
||||
CksumMax //!< Marker for number of cksum types
|
||||
};
|
||||
|
||||
AbstractProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
|
||||
|
@ -30,6 +30,7 @@ SampleConfigForm::SampleConfigForm(QWidget *parent)
|
||||
SampleProtocol::SampleProtocol(StreamBase *stream, AbstractProtocol *parent)
|
||||
: AbstractProtocol(stream, parent)
|
||||
{
|
||||
/* The configWidget is created lazily */
|
||||
configForm = NULL;
|
||||
}
|
||||
|
||||
@ -459,6 +460,7 @@ bool SampleProtocol::isProtocolFrameSizeVariable() const
|
||||
|
||||
QWidget* SampleProtocol::configWidget()
|
||||
{
|
||||
/* Lazy creation of the configWidget */
|
||||
if (configForm == NULL)
|
||||
{
|
||||
configForm = new SampleConfigForm;
|
||||
|
Loading…
Reference in New Issue
Block a user