Tuesday, June 16, 2015

Thread Safe Singleton XMLReader with QMutex and boost property tree

Singleton design pattern is used widely when only one instance of an object needs to be created in the application domain. In order to achieve secure creation of singleton instance in multithreaded environments, locking mechanism must be taken into consideration to provide thread safety.

XML configuration settings file access can be handled by creating a thread-safe singleton XMLParser class. Boost library has got a Property Tree library, boost::property_tree , which populates a tree data structure that is representing the existing XML file content.

boost::property_tree makes it easy to load an existing XML file into application. In order to provide thread safety for singleton XMLParser , QT application development framework supplied QMutex class can be used.

Following sample project created by qt creator and contains following files :

1-SingletonXMLParser.pro
2-XmlParser.h
3-XmlParser.cpp
4-main.cpp



SingletonXMLParser.pro file contains project configuration :

QT       += core
TARGET    = SingletonXMLParser
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE  = app
SOURCES  += main.cpp \
            XmlParser.cpp
HEADERS  += XmlParser.h

In this example project, XMLParser.h header file contains the Settings struct which is going to hold data loaded from XML file. Also the name of the XML file is declared in the header file with a #define directive.

Requirements to make XMLParser class a Thread-Safe Singleton is handled by

1- Making constructor private
2- Adding a static XMLParser variable
3- Static Instance creator method
4- QMutex variable for locking


Example ConfSettings.xml file contains following data and placed under an accessible folder :


#ifndef XMLPARSER_H
#define XMLPARSER_H

#define CONF_SETTINGS_FILE "ConfSettings.xml"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

#include <QMutex>

struct Settings
{
    std::string ipAddress;
    std::string userName;
};

class XMLParser
{
public:
    static XMLParser& instance();
    ~XMLParser();
    Settings getSettings();

private:
    XMLParser();
    Settings configSettings;
    static std::auto_ptr<XMLParser> mInstance;
    static QMutex mMutex;
};

#endif // XMLPARSER_H


XMLParser.cpp file contains implementation details for

1- private constructor
2- static instance creator method
3- static variables


#include "XmlParser.h"

std::auto_ptr<XMLParser> XMLParser::mInstance;
QMutex XMLParser::mMutex(QMutex::Recursive);

XMLParser::XMLParser()
{
    boost::property_tree::ptree config;
    read_xml(CONF_SETTINGS_FILE, config);

    configSettings.ipAddress = config.get<std::string>("ftp.ipAddress");
    configSettings.userName = config.get<std::string>("ftp.userName");
}

XMLParser::~XMLParser()
{
}

XMLParser& XMLParser::instance()
{
    mMutex.lock();
    if (mInstance.get() == 0)
    {
        try
        {
            mInstance.reset(new XMLParser);
        }
        catch (std::bad_alloc&)
        {
            throw;
        }
    }
    mMutex.unlock();
    return *mInstance;
}

Settings XMLParser::getSettings()
{
    return configSettings;
}


In the constructor of the XMLParser class CONF_SETTINGS_FILE is loaded into boost::property_tree::ptree type config variable. Then by applying the get method of boost::property_tree::ptree required elements from the XML document are retrieved into the application.

Static instance() method of XMLParser provides thread safety by calling lock() and unlock() methods of QMutex instance.

Main method in the main.cpp file calls the static instance() method of thread-safe singleton XMLParser class and then loads the config settings into to Settings struct.

#include "XmlParser.h"

int main()
{
    Settings confSettings = XMLParser::instance().getSettings();

    std::cout << confSettings.ipAddress << std::endl;
    std::cout << confSettings.userName << std::endl;

    return 0;
}

Output of the execution of this program shows ipAddress and userName element values from ConfSettings.xml file on the terminal.


Saturday, March 28, 2015

Serialize C++ Object with QString Instance Variables

boost::serialization library can be used to serialize and deserialize the state of QString variables in a C++ program.
By default boost::serialization library can not serialize a directly given QString variable, so you need an extra Serializer implementation for your serialization and deserialization requirements.

When you try to serialize a QString variable directly by using boost::serialization library, compiler gives errors about missing serialize method as follows :

error: 'class QString' has no member named 'serialize'

In order to use boost::serialization library in your applications, it is required to have libboost-all-dev library on your OS which contains libboost-serialization-dev. Following terminal command installs required boost libraries on linux OS :

$ sudo apt-get install libboost-all-dev

After installing boost serialization library, you can start including related header files into your application.

Following sample project created by qt creator and contains following files :

1-BoostSerializeQString.pro
2-QStringSerializer.h
3-User.h
4-main.cpp



BoostSerializeQString.pro file contains project configuration.

QT       += core
TARGET    = BoostSerializeQString
CONFIG   += console
CONFIG   -= app_bundle
TEMPLATE  = app
LIBS     += -lboost_serialization

SOURCES  += main.cpp

HEADERS  += QStringSerializer.h \
            User.h

boost_serialization library is included into this Qt Project by adding "LIBS += -lboost_serialization" line.
In this example User class contains two QString instance variables to serialize and deserialize. When saving and loading User class it is required to save and load QString variable state properly. Also, User class has an intrusive serialize function. For User class case, the serialize function is implemented as a member of the class.

#ifndef USER_H
#define USER_H

class User
{
public:

    User() {}

    User(const QString &name, const QString &surname)
    {
        this->name = name;
        this->surname = surname;
    }

    QString getName() { return name; }
    QString getSurname() { return surname; }

private:
    QString name;
    QString surname;

    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        // serialize deserialize QString instance variables
        ar & BOOST_SERIALIZATION_NVP(name);
        ar & BOOST_SERIALIZATION_NVP(surname);
    }

};

#endif // USER_H


QStringSerializer.h file contains save and load functions which are going to be invoked during serialization and deserialization process of QString instance variables.

By declaring non-intrusive serialization mechanism we were able to implement serialization for QString without changing its original class definition.

boost::serialization is able to work on std::string type correctly, so it is required to retrieve std::string value of QString for serialization. And also for the reverse operation it is required to construct QString from loaded std::string value.

QString has got both toStdString and fromStdString functions to achieve these requirements.

Inside serialize and deserialize functions different statements are executed so it is required to implement save and load functions separately.

Depending on the type of the archieve used for saving or loading current QString variable, save or load function is invoked.

#ifndef QSTRINGSERIALIZER_H
#define QSTRINGSERIALIZER_H

namespace boost {
    namespace serialization {

        template<class Archive>
        void save( Archive & ar, const QString& qStringParam, const unsigned int )
        {
            // save class member variables
            std::string stdString = qStringParam.toStdString();
            ar & BOOST_SERIALIZATION_NVP(stdString);
        }

        template<class Archive>
        void load( Archive & ar, QString& qStringParam, const unsigned int )
        {
            // load class member variables
            std::string stdString;
            ar & BOOST_SERIALIZATION_NVP(stdString);
            qStringParam = qStringParam.fromStdString(stdString);
        }

        template<class Archive>
        void serialize(Archive & ar, QString & t, const unsigned int file_version)
        {
            split_free(ar, t, file_version);
        }

    } // namespace serialization
} // namespace boost
#endif // QSTRINGSERIALIZER_H


main method in main.cpp file contains two code blocks which are respectively used for serialization and deserialization of User object with QString instance variables or states. After reconstructing User object, QString instance variables name and surname are initialized with the original values as serialized.

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/nvp.hpp>

#include <QString>
#include <fstream>
#include <iostream>

#include "User.h"
#include "QStringSerializer.h"

using namespace std;

int main()
{
        {
            // Initialize User object to serialize with data
            User user("userName","userSurname");
            std::ofstream ofs("stateInfoFile.xml");
            boost::archive::xml_oarchive oa(ofs);
            // write class instance to archive
            oa & BOOST_SERIALIZATION_NVP(user);
        }

        {
            User user;
            std::ifstream ifs("stateInfoFile.xml");
            boost::archive::xml_iarchive ia(ifs);
            // read class instance back from archive
            ia & BOOST_SERIALIZATION_NVP(user);

            std::cout << "Name : " << user.getName().toStdString() << std::endl;
            std::cout << "Surname : " << user.getSurname().toStdString() << std::endl;
        }
}


User object state is saved into stateInfoFile.xml file and loaded back from the same xml file again for object reconstruction. stateInfoFile.xml file is an xml file and its content is as follows :


Thursday, September 25, 2014

Using Enumeration in C++

Enumeration in C++ is a user defined type that contains a set of constant values. An enumeration consists of an identifier and a list of types. Every type in an enumeration corresponds to a constant value. Default value for the first type is integer 0 and the next one gets the integer value 1. But an enumeration type can have a value other than default integer 0. Therefore an enum type can be casted to integer.


Following sample project created by qt creator and contains following files:
1- UsingEnumeration.pro
2- device.h
3- device.cpp
4- main.cpp



UsingEnumeration.pro file contains project configuration.

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp \
    device.cpp
HEADERS += \
    device.h

device.h header file contains definition for Device class and Status enumeration.

#ifndef DEVICE_H
#define DEVICE_H

namespace UsingEnumsSample
{

enum Status {
    IDLE = 0,
    ACTIVE = 1,
    DEAD = 2
};

class Device
{
public:

    Device();
    void setStatus(Status pStatus);
    Status getStatus();

private:
    Status status;
};

}

#endif // DEVICE_H


device.cpp file contains implementation for Device class. setDevice method accepts an enumerator and assigns the passed value to Device class private enumeration member.

#include "device.h"

namespace UsingEnumsSample
{

Device::Device()
{
}

void Device::setStatus(Status pStatus)
{
    status = pStatus;
}

Status Device::getStatus()
{
    return status;
}

}

main.cpp method creates a Device instance and calls its setStatus and getStatus methods to set the Status value to the private Status enumeration member.

#include <iostream>
#include "device.h"

using namespace std;
using namespace UsingEnumsSample;

int main()
{
    Device device;
    device.setStatus(ACTIVE);
    cout << device.getStatus() << endl;
    device.setStatus(IDLE);
    cout << device.getStatus() << endl;
    return 0;
}

When the main method is executed, values of the Status member is displayed on the terminal which are consequently 1 and 0 as the program runs.

Wednesday, August 13, 2014

boost::array of std::string items in Qt Creator

boost::array is a template class which enables it to be able to be declared for different type of items. There exists an array as a member inside boost:array template class declaration so boost:array also acts a C-array wrapper with fixed number of items inside it.

Following sample project created by qt creator and contains following files:
1- BoostArrayOfStrings.pro
2- main.cpp



BoostArrayOfStrings.pro file contains project configuration.

TEMPLATE = app
CONFIG += console

SOURCES += main.cpp

INCLUDEPATH += /home/tufan/boost_1_55_0

Boost header files and libraries are located under the directory : /home/tufan/boost_1_55_0

main.cpp file contains main method.

#include <boost/array.hpp>
#include <string.h>

using namespace std;

int main()
{
    typedef boost::array<string,3> boostArray;
    boostArray stringArray;

    stringArray[0] = "FirstStringMember";
    stringArray.at(1) = "SecondStringMember";
    stringArray.at(2) = "ThirdStringMember";

    // some common container operations
    cout << "size:     " << stringArray.size() << endl;
    cout << "empty:    " << boolalpha << stringArray.empty() << endl;
    cout << "front:    " << stringArray.front() << endl;
    cout << "back:     " << stringArray.back() << endl;
    cout << "elements:    " << endl;

    for(boostArray::iterator iter(stringArray.begin()); iter != stringArray.end(); ++iter)
    {
        cout << *iter << endl;
    }

    return 0;
}
boost array contains 3 string items. Members of the array are initialized by using array subscript operator and at() function.

size:     3
empty:    false
front:    FirstStringMember
back:     ThirdStringMember
elements:  
FirstStringMember
SecondStringMember
ThirdStringMember

Tuesday, August 12, 2014

boost::array of Integers in Qt Creator

boost::array provides C-style array declaration and usage with constant number of items inside it. When only static-constant sized arrays are required, then boost::array comes with a better memory management solution than std::vector.

After including boost libraries into a Qt Creator C++ project, it becomes easy to use boost::array type of members in your programs.

boost/array.hpp file contains boost::array type.

As the boost::array documentation indicates boost::array is the STL compliant container wrapper for arrays of constant size.



Following sample project created by qt creator and contains following files:

1- BoostArrayOfIntegers.pro
2- main.cpp


BoostArrayOfIntegers.pro file contains project configuration.
TEMPLATE = app
CONFIG += console

SOURCES += main.cpp

INCLUDEPATH += /home/tufan/boost_1_55_0

I have installed the boost library to the directory         :  /home/tufan/boost_1_55_0
and boost/array.hpp file is located at                           :  /home/tufan/boost_1_55_0/boost/array.hpp

so qt creator does not complain about path related errors.


There is also another installed boost library which contains an older version of boost libraries  at directory : /usr/include/boost


In BoostArrayOfIntegers.pro file I have stated that I will use the boost library from specific location and qt creator selected the library from : /home/tufan/boost_1_55_0


main.cpp file contains main method.

#include <boost/array.hpp>

using namespace std;

int main()
{
    typedef boost::array<int, 4> intArrayType;
    intArrayType myArray = {{1,2,3,4}};
    std::cout << "boost intArray content :" << "\n";
    for( intArrayType::const_iterator iterator = myArray.begin(),
         iteratorEnd = myArray.end();
         iterator != iteratorEnd; ++iterator )
    {
        cout << *iterator << endl;
    }

    return 0;
}
boost::array is initialized with 4 integer members in curly braces. I used an iterator to traverse the integer members of the boost::array.

When the project is executed the following terminal output is generated :

boost intArray content :
1
2
3
4