diff --git a/QsLog/QsLog.h b/QsLog/QsLog.h index 38663a13..f72e827c 100644 --- a/QsLog/QsLog.h +++ b/QsLog/QsLog.h @@ -31,7 +31,7 @@ #include #include -#define QS_LOG_VERSION "2.0b1" +#define QS_LOG_VERSION "2.0b3" namespace QsLogging { @@ -56,7 +56,7 @@ public: //! The helper forwards the streaming to QDebug and builds the final //! log message. - class Helper + class QSLOG_SHARED_OBJECT Helper { public: explicit Helper(Level logLevel) : diff --git a/QsLog/QsLog.pri b/QsLog/QsLog.pri index 01ddcbfa..0b464759 100644 --- a/QsLog/QsLog.pri +++ b/QsLog/QsLog.pri @@ -2,18 +2,22 @@ INCLUDEPATH += $$PWD #DEFINES += QS_LOG_LINE_NUMBERS # automatically writes the file and line for each log message #DEFINES += QS_LOG_DISABLE # logging code is replaced with a no-op DEFINES += QS_LOG_SEPARATE_THREAD # messages are queued and written from a separate thread + SOURCES += $$PWD/QsLogDest.cpp \ $$PWD/QsLog.cpp \ $$PWD/QsLogDestConsole.cpp \ - $$PWD/QsLogDestFile.cpp + $$PWD/QsLogDestFile.cpp \ + $$PWD/QsLogDestFunctor.cpp HEADERS += $$PWD/QSLogDest.h \ $$PWD/QsLog.h \ $$PWD/QsLogDestConsole.h \ $$PWD/QsLogLevel.h \ $$PWD/QsLogDestFile.h \ - $$PWD/QsLogDisableForThisFile.h + $$PWD/QsLogDisableForThisFile.h \ + $$PWD/QsLogDestFunctor.h OTHER_FILES += \ $$PWD/QsLogChanges.txt \ - $$PWD/QsLogReadme.txt + $$PWD/QsLogReadme.txt \ + $$PWD/LICENSE.txt diff --git a/QsLog/QsLogDest.cpp b/QsLog/QsLogDest.cpp index f2387278..ae9f44bc 100644 --- a/QsLog/QsLogDest.cpp +++ b/QsLog/QsLogDest.cpp @@ -26,11 +26,16 @@ #include "QsLogDest.h" #include "QsLogDestConsole.h" #include "QsLogDestFile.h" +#include "QsLogDestFunctor.h" #include namespace QsLogging { +Destination::~Destination() +{ +} + //! destination factory DestinationPtr DestinationFactory::MakeFileDestination(const QString& filePath, LogRotationOption rotation, const MaxSizeBytes &sizeInBytesToRotateAfter, @@ -52,4 +57,14 @@ DestinationPtr DestinationFactory::MakeDebugOutputDestination() return DestinationPtr(new DebugOutputDestination); } +DestinationPtr DestinationFactory::MakeFunctorDestination(QsLogging::Destination::LogFunction f) +{ + return DestinationPtr(new FunctorDestination(f)); +} + +DestinationPtr DestinationFactory::MakeFunctorDestination(QObject *receiver, const char *member) +{ + return DestinationPtr(new FunctorDestination(receiver, member)); +} + } // end namespace diff --git a/QsLog/QsLogDest.h b/QsLog/QsLogDest.h index 063f9ad7..a404487b 100644 --- a/QsLog/QsLogDest.h +++ b/QsLog/QsLogDest.h @@ -30,11 +30,14 @@ #include #include class QString; +class QObject; #ifdef QSLOG_IS_SHARED_LIBRARY #define QSLOG_SHARED_OBJECT Q_DECL_EXPORT +#elif QSLOG_IS_SHARED_LIBRARY_IMPORT +#define QSLOG_SHARED_OBJECT Q_DECL_IMPORT #else -#define QSLOG_SHARED_OBJECT /*Q_DECL_IMPORT*/ +#define QSLOG_SHARED_OBJECT #endif namespace QsLogging @@ -43,7 +46,10 @@ namespace QsLogging class QSLOG_SHARED_OBJECT Destination { public: - virtual ~Destination(){} + typedef void (*LogFunction)(const QString &message, Level level); + +public: + virtual ~Destination(); virtual void write(const QString& message, Level level) = 0; virtual bool isValid() = 0; // returns whether the destination was created correctly }; @@ -60,14 +66,14 @@ enum LogRotationOption struct QSLOG_SHARED_OBJECT MaxSizeBytes { MaxSizeBytes() : size(0) {} - MaxSizeBytes(qint64 size_) : size(size_) {} + explicit MaxSizeBytes(qint64 size_) : size(size_) {} qint64 size; }; struct QSLOG_SHARED_OBJECT MaxOldLogCount { MaxOldLogCount() : count(0) {} - MaxOldLogCount(int count_) : count(count_) {} + explicit MaxOldLogCount(int count_) : count(count_) {} int count; }; @@ -82,6 +88,10 @@ public: const MaxSizeBytes &sizeInBytesToRotateAfter = MaxSizeBytes(), const MaxOldLogCount &oldLogsToKeep = MaxOldLogCount()); static DestinationPtr MakeDebugOutputDestination(); + // takes a pointer to a function + static DestinationPtr MakeFunctorDestination(Destination::LogFunction f); + // takes a QObject + signal/slot + static DestinationPtr MakeFunctorDestination(QObject *receiver, const char *member); }; } // end namespace diff --git a/QsLog/QsLogDestFunctor.cpp b/QsLog/QsLogDestFunctor.cpp new file mode 100644 index 00000000..601139d9 --- /dev/null +++ b/QsLog/QsLogDestFunctor.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2014, Razvan Petru +// Copyright (c) 2014, Omar Carey +// All rights reserved. + +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: + +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// * The name of the contributors may not be used to endorse or promote products +// derived from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "QsLogDestFunctor.h" +#include +#include + +QsLogging::FunctorDestination::FunctorDestination(LogFunction f) + : QObject(NULL) + , mLogFunction(f) +{ +} + +QsLogging::FunctorDestination::FunctorDestination(QObject *receiver, const char *member) + : QObject(NULL) + , mLogFunction(NULL) +{ + connect(this, SIGNAL(logMessageReady(QString,int)), receiver, member, Qt::QueuedConnection); +} + + +void QsLogging::FunctorDestination::write(const QString &message, QsLogging::Level level) +{ + if (mLogFunction) + mLogFunction(message, level); + + if (level > QsLogging::TraceLevel) + emit logMessageReady(message, static_cast(level)); +} + +bool QsLogging::FunctorDestination::isValid() +{ + return true; +} diff --git a/QsLog/QsLogDestFunctor.h b/QsLog/QsLogDestFunctor.h new file mode 100644 index 00000000..b4c7fc1f --- /dev/null +++ b/QsLog/QsLogDestFunctor.h @@ -0,0 +1,59 @@ +// Copyright (c) 2014, Razvan Petru +// Copyright (c) 2014, Omar Carey +// All rights reserved. + +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: + +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, this +// list of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// * The name of the contributors may not be used to endorse or promote products +// derived from this software without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef QSLOGDESTFUNCTOR_H +#define QSLOGDESTFUNCTOR_H + +#include "QSLogDest.h" +#include + +namespace QsLogging +{ +// Offers various types of function-like sinks. +// This is an advanced destination type. Depending on your configuration, LogFunction might be +// called from a different thread or even a different binary. You should not access QsLog from +// inside LogFunction and should not perform any time-consuming operations. +// logMessageReady is connected through a queued connection and trace messages are not included +class FunctorDestination : public QObject, public Destination +{ + Q_OBJECT +public: + explicit FunctorDestination(LogFunction f); + FunctorDestination(QObject *receiver, const char *member); + + virtual void write(const QString &message, Level level); + virtual bool isValid(); + +protected: + // int used to avoid registering a new enum type + Q_SIGNAL void logMessageReady(const QString &message, int level); + +private: + LogFunction mLogFunction; +}; +} + +#endif // QSLOGDESTFUNCTOR_H diff --git a/QsLog/QsLogSharedLibrary.pro b/QsLog/QsLogSharedLibrary.pro index 2cf52acc..51320684 100644 --- a/QsLog/QsLogSharedLibrary.pro +++ b/QsLog/QsLogSharedLibrary.pro @@ -11,6 +11,11 @@ TEMPLATE = lib DESTDIR = $$PWD/build-QsLogShared OBJECTS_DIR = $$DESTDIR/obj +MOC_DIR = $$DESTDIR/moc + +win32 { + DEFINES += QSLOG_IS_SHARED_LIBRARY +} unix:!macx { # make install will install the shared object in the appropriate folders diff --git a/YACReader/yacreader_local_client.cpp b/YACReader/yacreader_local_client.cpp index ee4a795b..6450593c 100644 --- a/YACReader/yacreader_local_client.cpp +++ b/YACReader/yacreader_local_client.cpp @@ -45,7 +45,7 @@ bool YACReaderLocalClient::requestComicInfo(quint64 libraryId, ComicDB & comic, out << (quint32)(block.size() - sizeof(quint32)); int written, previousWritten = 0; - int tries = 0; + quint16 tries = 0; while(written != block.size() && tries < 200) { written += localSocket->write(block); @@ -63,27 +63,36 @@ bool YACReaderLocalClient::requestComicInfo(quint64 libraryId, ComicDB & comic, //QByteArray data; tries = 0; - while(localSocket->bytesAvailable() < sizeof(quint32) && tries < 10) + int dataAvailable = 0; + QByteArray packageSize; + localSocket->waitForReadyRead(1000); + while(packageSize.size() < sizeof(quint32) && tries < 20) { + packageSize.append(localSocket->read(sizeof(quint32) - packageSize.size())); localSocket->waitForReadyRead(100); - tries++; + if(dataAvailable == packageSize.size()) + { + tries++; //TODO apply 'tries' fix + } + dataAvailable = packageSize.size(); } - if(tries == 10) + if(tries == 20) { localSocket->close(); QLOG_ERROR() << "Requesting Comic Info : unable to read package size"; return false; } - QDataStream sizeStream(localSocket->read(sizeof(quint32))); + QDataStream sizeStream(packageSize);//localSocket->read(sizeof(quint32))); sizeStream.setVersion(QDataStream::Qt_4_8); quint32 totalSize = 0; sizeStream >> totalSize; - + QByteArray data; tries = 0; int dataRead = 0; - while(data.length() < totalSize && tries < 20 ) + localSocket->waitForReadyRead(1000); + while(data.length() < totalSize && tries < 20 ) { data.append(localSocket->readAll()); if(data.length() < totalSize) @@ -92,10 +101,11 @@ bool YACReaderLocalClient::requestComicInfo(quint64 libraryId, ComicDB & comic, tries++; dataRead = data.length(); } - if(tries == 20) + + if(tries == 20) { localSocket->close(); - QLOG_ERROR() << QString("Requesting Comic Info : unable to read data (%1,%2)").arg(data.length()).arg(totalSize); + QLOG_ERROR() << "Requesting Comic Info : unable to read data (" << data.length() << "," << totalSize << ")"; return false; } @@ -127,7 +137,8 @@ bool YACReaderLocalClient::sendComicInfo(quint64 libraryId, ComicDB & comic) out.device()->seek(0); out << (quint32)(block.size() - sizeof(quint32)); - int written, previousWritten = 0; + int written, previousWritten; + written = previousWritten = 0; int tries = 0; while(written != block.size() && tries < 100) { diff --git a/YACReaderLibrary/yacreader_local_server.cpp b/YACReaderLibrary/yacreader_local_server.cpp index 4bd647ae..08d3c635 100644 --- a/YACReaderLibrary/yacreader_local_server.cpp +++ b/YACReaderLibrary/yacreader_local_server.cpp @@ -95,19 +95,26 @@ void YACReaderClientConnectionWorker::run() quint64 libraryId; ComicDB comic; int tries = 0; - //QByteArray data; - while(clientConnection->bytesAvailable() < sizeof(quint32) && tries < 200) + int dataAvailable = 0; + QByteArray packageSize; + clientConnection->waitForReadyRead(1000); + while(packageSize.size() < sizeof(quint32) && tries < 20) { - clientConnection->waitForReadyRead(10); - tries++; + packageSize.append(clientConnection->read(sizeof(quint32) - packageSize.size())); + clientConnection->waitForReadyRead(100); + if(dataAvailable == packageSize.size()) + { + tries++; + } + dataAvailable = packageSize.size(); } - if(tries == 200) + if(tries == 20) { QLOG_ERROR() << "Local connection: unable to read the message size"; return; } - QDataStream sizeStream(clientConnection->read(sizeof(quint32))); + QDataStream sizeStream(packageSize); sizeStream.setVersion(QDataStream::Qt_4_8); quint32 totalSize = 0; sizeStream >> totalSize;