Skip to content

Commit

Permalink
removed c style casts and eliminated all clang warnings, ... (itay-gr…
Browse files Browse the repository at this point in the history
…udev#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
  • Loading branch information
jbuckmccready authored and itay-grudev committed Dec 3, 2017
1 parent 4f03651 commit a956ae4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 51 deletions.
94 changes: 44 additions & 50 deletions singleapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <QtCore/QSharedMemory>
#include <QtCore/QStandardPaths>
#include <QtCore/QCryptographicHash>
#include <QtCore/QDataStream>
#include <QtNetwork/QLocalServer>
#include <QtNetwork/QLocalSocket>

Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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();
Expand All @@ -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();

Expand Down Expand Up @@ -272,39 +271,34 @@ 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];

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:
connectionType = InvalidConnection;
}
// 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);

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

Expand Down Expand Up @@ -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 );
Expand All @@ -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;
Expand All @@ -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 );
}
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 7 additions & 1 deletion singleapplication_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand All @@ -54,7 +60,7 @@ Q_OBJECT
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
Expand Down

0 comments on commit a956ae4

Please sign in to comment.