removed c style casts and eliminated all clang warnings, ... (#38)

* removed c style casts and eliminated all clang warnings, fixed instanceId reading from only one byte in deserialization of message, cleaned up serialization code using QDataStream, changed connection type to use quint8 enum rather than char

* renamed SingleAppConnectionType to ConnectionType, added initialization values to all ConnectionType enum cases
This commit is contained in:
Jedidiah Buck McCready 2017-12-03 09:04:02 -08:00 committed by Itay Grudev
parent 4f03651072
commit a956ae47d1
2 changed files with 50 additions and 50 deletions

View File

@ -29,6 +29,7 @@
#include <QtCore/QSharedMemory> #include <QtCore/QSharedMemory>
#include <QtCore/QStandardPaths> #include <QtCore/QStandardPaths>
#include <QtCore/QCryptographicHash> #include <QtCore/QCryptographicHash>
#include <QtCore/QDataStream>
#include <QtNetwork/QLocalServer> #include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket> #include <QtNetwork/QLocalSocket>
@ -46,11 +47,6 @@
#include "singleapplication_p.h" #include "singleapplication_p.h"
static const char NewInstance = 'N';
static const char SecondaryInstance = 'S';
static const char Reconnect = 'R';
static const char InvalidConnection = '\0';
SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) : q_ptr( q_ptr ) { SingleApplicationPrivate::SingleApplicationPrivate( SingleApplication *q_ptr ) : q_ptr( q_ptr ) {
server = nullptr; server = nullptr;
socket = nullptr; socket = nullptr;
@ -64,7 +60,7 @@ SingleApplicationPrivate::~SingleApplicationPrivate()
} }
memory->lock(); memory->lock();
InstancesInfo* inst = (InstancesInfo*)memory->data(); InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
if( server != nullptr ) { if( server != nullptr ) {
server->close(); server->close();
delete server; delete server;
@ -162,7 +158,7 @@ void SingleApplicationPrivate::startPrimary( bool resetMemory )
// Reset the number of connections // Reset the number of connections
memory->lock(); memory->lock();
InstancesInfo* inst = (InstancesInfo*)memory->data(); InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
if( resetMemory ) { if( resetMemory ) {
inst->secondary = 0; inst->secondary = 0;
@ -185,7 +181,7 @@ void SingleApplicationPrivate::startSecondary()
#endif #endif
} }
void SingleApplicationPrivate::connectToPrimary( int msecs, char connectionType ) void SingleApplicationPrivate::connectToPrimary( int msecs, ConnectionType connectionType )
{ {
// Connect to the Local Server of the Primary Instance if not already // Connect to the Local Server of the Primary Instance if not already
// connected. // connected.
@ -211,11 +207,14 @@ void SingleApplicationPrivate::connectToPrimary( int msecs, char connectionType
// Initialisation message according to the SingleApplication protocol // Initialisation message according to the SingleApplication protocol
if( socket->state() == QLocalSocket::ConnectedState ) { if( socket->state() == QLocalSocket::ConnectedState ) {
// Notify the parent that a new instance had been started; // Notify the parent that a new instance had been started;
QByteArray initMsg = blockServerName.toLatin1(); QByteArray initMsg;
QDataStream writeStream(&initMsg, QIODevice::WriteOnly);
initMsg.append( connectionType ); writeStream.setVersion(QDataStream::Qt_5_6);
initMsg.append( (const char *)&instanceNumber, sizeof(quint32) ); writeStream << blockServerName.toLatin1();
initMsg.append( QByteArray::number( qChecksum( initMsg.constData(), initMsg.length() ), 256) ); writeStream << static_cast<quint8>(connectionType);
writeStream << instanceNumber;
quint16 checksum = qChecksum(initMsg.constData(), static_cast<quint32>(initMsg.length()));
writeStream << checksum;
socket->write( initMsg ); socket->write( initMsg );
socket->flush(); socket->flush();
@ -228,7 +227,7 @@ qint64 SingleApplicationPrivate::primaryPid()
qint64 pid; qint64 pid;
memory->lock(); memory->lock();
InstancesInfo* inst = (InstancesInfo*)memory->data(); InstancesInfo* inst = static_cast<InstancesInfo*>(memory->data());
pid = inst->primaryPid; pid = inst->primaryPid;
memory->unlock(); memory->unlock();
@ -272,41 +271,36 @@ void SingleApplicationPrivate::slotConnectionEstablished()
QLocalSocket *nextConnSocket = server->nextPendingConnection(); QLocalSocket *nextConnSocket = server->nextPendingConnection();
// Verify that the new connection follows the SingleApplication protocol quint32 instanceId = 0;
char connectionType = InvalidConnection; ConnectionType connectionType = InvalidConnection;
quint32 instanceId;
QByteArray initMsg, tmp;
if( nextConnSocket->waitForReadyRead( 100 ) ) { if( nextConnSocket->waitForReadyRead( 100 ) ) {
tmp = nextConnSocket->read( blockServerName.length() ); // read all data from message in same order/format as written
// Verify that the socket data start with blockServerName QByteArray msgBytes = nextConnSocket->read(nextConnSocket->bytesAvailable() - static_cast<qint64>(sizeof(quint16)));
if( tmp == blockServerName.toLatin1() ) { QByteArray checksumBytes = nextConnSocket->read(sizeof(quint16));
initMsg = tmp; QDataStream readStream(msgBytes);
connectionType = nextConnSocket->read( 1 )[0]; readStream.setVersion(QDataStream::Qt_5_6);
switch( connectionType ) { // server name
case NewInstance: QByteArray latin1Name;
case SecondaryInstance: readStream >> latin1Name;
case Reconnect: // connectioon type
{ quint8 connType = InvalidConnection;
initMsg += connectionType; readStream >> connType;
tmp = nextConnSocket->read( sizeof(quint32) ); connectionType = static_cast<ConnectionType>(connType);
const char * data = tmp.constData(); // instance id
instanceId = (quint32)*data; readStream >> instanceId;
initMsg += tmp; // checksum
// Verify the checksum of the initMsg quint16 msgChecksum = 0;
QByteArray checksum = QByteArray::number( QDataStream checksumStream(checksumBytes);
qChecksum( initMsg.constData(), initMsg.length() ), checksumStream.setVersion(QDataStream::Qt_5_6);
256 checksumStream >> msgChecksum;
);
tmp = nextConnSocket->read( checksum.length() ); const quint16 actualChecksum = qChecksum(msgBytes.constData(), static_cast<quint32>(msgBytes.length()));
if( checksum == tmp )
break; // Otherwise set to invalid connection (next line) if (readStream.status() != QDataStream::Ok || QLatin1String(latin1Name) != blockServerName || msgChecksum != actualChecksum) {
}
default:
connectionType = InvalidConnection; connectionType = InvalidConnection;
} }
} }
}
if( connectionType == InvalidConnection ) { if( connectionType == InvalidConnection ) {
nextConnSocket->close(); nextConnSocket->close();
@ -395,7 +389,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
// Attempt to attach to the memory segment // Attempt to attach to the memory segment
if( d->memory->attach() ) { if( d->memory->attach() ) {
d->memory->lock(); d->memory->lock();
InstancesInfo* inst = (InstancesInfo*)d->memory->data(); InstancesInfo* inst = static_cast<InstancesInfo*>(d->memory->data());
if( ! inst->primary ) { if( ! inst->primary ) {
d->startPrimary( false ); d->startPrimary( false );
@ -409,7 +403,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
d->instanceNumber = inst->secondary; d->instanceNumber = inst->secondary;
d->startSecondary(); d->startSecondary();
if( d->options & Mode::SecondaryNotification ) { if( d->options & Mode::SecondaryNotification ) {
d->connectToPrimary( timeout, SecondaryInstance ); d->connectToPrimary( timeout, SingleApplicationPrivate::SecondaryInstance );
} }
d->memory->unlock(); d->memory->unlock();
return; return;
@ -419,7 +413,7 @@ SingleApplication::SingleApplication( int &argc, char *argv[], bool allowSeconda
} }
} }
d->connectToPrimary( timeout, NewInstance ); d->connectToPrimary( timeout, SingleApplicationPrivate::NewInstance );
delete d; delete d;
::exit( EXIT_SUCCESS ); ::exit( EXIT_SUCCESS );
} }
@ -465,7 +459,7 @@ bool SingleApplication::sendMessage( QByteArray message, int timeout )
if( isPrimary() ) return false; if( isPrimary() ) return false;
// Make sure the socket is connected // Make sure the socket is connected
d->connectToPrimary( timeout, Reconnect ); d->connectToPrimary( timeout, SingleApplicationPrivate::Reconnect );
d->socket->write( message ); d->socket->write( message );
bool dataWritten = d->socket->flush(); bool dataWritten = d->socket->flush();

View File

@ -46,6 +46,12 @@ struct InstancesInfo {
class SingleApplicationPrivate : public QObject { class SingleApplicationPrivate : public QObject {
Q_OBJECT Q_OBJECT
public: public:
enum ConnectionType : quint8 {
InvalidConnection = 0,
NewInstance = 1,
SecondaryInstance = 2,
Reconnect = 3
};
Q_DECLARE_PUBLIC(SingleApplication) Q_DECLARE_PUBLIC(SingleApplication)
SingleApplicationPrivate( SingleApplication *q_ptr ); SingleApplicationPrivate( SingleApplication *q_ptr );
@ -54,7 +60,7 @@ public:
void genBlockServerName( int msecs ); void genBlockServerName( int msecs );
void startPrimary( bool resetMemory ); void startPrimary( bool resetMemory );
void startSecondary(); void startSecondary();
void connectToPrimary( int msecs, char connectionType ); void connectToPrimary(int msecs, ConnectionType connectionType );
qint64 primaryPid(); qint64 primaryPid();
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX