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

View File

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