[SF] Serialization Qt classes (with examples)

RCF support and general discussion.
Post Reply
acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

[SF] Serialization Qt classes (with examples)

Post by acDev »

Just realized the serialization support the following classes: QString, QList<T>, QStringList.

File "SF/include/QString.hpp"

Code: Select all

#ifndef INCLUDE_SF_QSTRING_HPP
#define INCLUDE_SF_QSTRING_HPP

#include <QByteArray>
#include <QString>

#include <boost/config.hpp>

#include <SF/Archive.hpp>
#include <SF/Stream.hpp>

namespace SF {

    // QString    
    inline void serialize_vc6(SF::Archive & ar, QString & qs, const unsigned int)
    {
        if (ar.isRead())
        {
            boost::uint32_t count = 0;
            ar & count;

            qs.resize(0);
            
            if (count) 
            {
                SF::IStream &is = *ar.getIstream();            
                QByteArray qba(count, 0);   // init buffer and fill zero

                // Size field is verified, so read everything in one go. 
                RCF_VERIFY(
                    is.read(qba.data(), count) == count,
                    RCF::Exception(RCF::_SfError_ReadFailure()))
                    (count);

                // Appends the byte array (qba) to this string.
                // The given byte array is converted to Unicode using the fromUtf8() function.
                qs.append(qba);
            }    
        }
        else if (ar.isWrite())
        {
            QByteArray qba(qs.toUtf8());
            boost::uint32_t count = static_cast<boost::uint32_t >(qba.size());
            ar & count;
            ar.getOstream()->writeRaw(qba.data(), count);
        }

    }

} // namespace SF

#endif // ! INCLUDE_SF_QSTRING_HPP
File "SF/include/QList.hpp"

Code: Select all

#ifndef INCLUDE_SF_QLIST_HPP
#define INCLUDE_SF_QLIST_HPP

#include <QList>

#include <SF/SerializeStl.hpp>

namespace SF {

    // QList
    template<typename T>
    inline void serialize_vc6(SF::Archive &ar, QList<T> &t, const unsigned int)
    {
        serializeStlContainer<PushBackSemantics, NoReserveSemantics>(ar, t);
    }

} // namespace SF

#endif // ! INCLUDE_SF_QLIST_HPP
File "SF/include/QStringList.hpp"

Code: Select all

#ifndef INCLUDE_SF_QSTRINGLIST_HPP
#define INCLUDE_SF_QSTRINGLIST_HPP

#include <QStringList>

#include <SF/SerializeStl.hpp>

namespace SF {

    // QStringList
    inline void serialize_vc6(SF::Archive &ar, QStringList &t, const unsigned int)
    {
        serializeStlContainer<PushBackSemantics, NoReserveSemantics>(ar, t);
    }

} // namespace SF

#endif // ! INCLUDE_SF_QSTRINGLIST_HPP
Last edited by acDev on Wed Oct 09, 2013 2:40 pm, edited 1 time in total.

jarl
Posts: 238
Joined: Mon Oct 03, 2011 4:53 am
Contact:

Re: [SF] Serialization Qt classes (with examples)

Post by jarl »

Thanks - that's great! If you don't mind, I will include this in the RCF distribution, for the other QT users out there.
Kind Regards

Jarl Lindrud
Delta V Software
http://www.deltavsoft.com

acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

Re: [SF] Serialization Qt classes (with examples)

Post by acDev »

jarl wrote:Thanks - that's great! If you don't mind, I will include this in the RCF distribution, for the other QT users out there.
Of course, you can include.

At week plan to do serialization of the following classes: QByteArray, QRgb, QDateTime, QMap, QPair, QHostAddress.

acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

Re: [SF] Serialization Qt classes (with examples)

Post by acDev »

In the first post changed the implementation QString.

Serialization QByteArray. File "SF/QByteArray.hpp"

Code: Select all

#ifndef INCLUDE_SF_QBYTEARRAY_HPP
#define INCLUDE_SF_QBYTEARRAY_HPP

#include <QByteArray>

#include <boost/config.hpp>

#include <SF/Archive.hpp>
#include <SF/Stream.hpp>

namespace SF {

    // QByteArray    
    inline void serializeQByteArray(SF::Archive & ar, QByteArray & qba)
    {
        if (ar.isRead())
        {
            boost::uint32_t count = 0;
            ar & count;
                
            qba.resize(count);
                        
            if (count) 
            {
                SF::IStream &is = *ar.getIstream();            

                // Size field is verified, so read everything in one go. 
                RCF_VERIFY(
                    is.read(qba.data(), count) == count,
                    RCF::Exception(RCF::_SfError_ReadFailure()))
                    (count);
            }
        }
        else if (ar.isWrite())
        {
            boost::uint32_t count = static_cast<boost::uint32_t >(qba.size());
            ar & count;
            ar.getOstream()->writeRaw(qba.data(), count);
        }

    }

    // QByteArray
    inline void serialize_vc6(SF::Archive & ar, QByteArray & qba, const unsigned int)
    {
        serializeQByteArray(ar, qba);
    }


} // namespace SF

#endif // ! INCLUDE_SF_QBYTEARRAY_HPP


Serialization QHostAddress. File "SF/QHostAddress.hpp"

Code: Select all

#ifndef INCLUDE_SF_QHOSTADDRESS_HPP
#define INCLUDE_SF_QHOSTADDRESS_HPP

#include <QHostAddress>

#include <boost/config.hpp>

#include <SF/Archive.hpp>
#include <SF/QByteArray.hpp> 

namespace SF {

    // QHostAddress
    inline void serialize(SF::Archive & ar, QHostAddress & qha)
    {
      if (ar.isRead())
      {
        QByteArray data;
        serializeQByteArray(ar, data);
        QDataStream qdsi(data);   // QIODevice::ReadOnly
        qdsi >> qha;
      }
      else if (ar.isWrite())
      {
        QByteArray data;
        QDataStream qdso(&data, QIODevice::ReadWrite);
        qdso << qha;
        serializeQByteArray(ar, data);
      }
    }    

} // namespace SF

#endif // ! INCLUDE_SF_QHOSTADDRESS_HPP
Serialization QMap. File "SF/QMap.hpp"

Code: Select all

#ifndef INCLUDE_SF_QMAP_HPP
#define INCLUDE_SF_QMAP_HPP

#include <QMap>

#include <SF/SerializeStl.hpp>

namespace SF {

    // QMap
    template<typename K, typename T>
    inline void serialize_vc6(Archive &ar, QMap<K,T> &t, const unsigned int)
    {
        typedef typename QMap<K,T>::iterator Iterator;
        typedef typename QMap<K,T>::key_type Key;
        typedef typename QMap<K,T>::mapped_type Value;

        if (ar.isRead())
        {
          t.clear();
          boost::uint32_t count = 0;
          ar & count;

          for (boost::uint32_t i=0; i<count; i++)
          {
            Key key;
            ar & key;
            Value value;
            ar & value;
            t.insert(key, value);
          }
        }
        else if (ar.isWrite())
        {
          boost::uint32_t count = static_cast<boost::uint32_t>(t.size());
          ar & count;
          Iterator it = t.begin();
          for (boost::uint32_t i=0; i<count; i++)
          {
            ar & it.key();
            ar & it.value();
            it++;
          }
        }
    }
}

#endif // ! INCLUDE_SF_QMAP_HPP
Serialization QDataStream, QDateTime, QPair. File "SF/QCore.hpp"

Code: Select all

#ifndef INCLUDE_SF_QCORE_HPP
#define INCLUDE_SF_QCORE_HPP

#include <QByteArray>
#include <QDataStream>
#include <QDateTime>
#include <QPair>

#include <boost/config.hpp>

#include <SF/Archive.hpp>
#include <SF/Stream.hpp>

#include <SF/QByteArray.hpp>
#include <SF/QString.hpp>
#include <SF/QList.hpp>
#include <SF/QStringList.hpp>
#include <SF/QMap.hpp>

namespace SF {
                
    inline void serializeQDataStream(SF::Archive & ar, QDataStream & qds)
    {
      if (ar.isRead())
      {         
        if (qds.device()->isWritable())    // QIODevice::WriteOnly
        {
          //qds.resetStatus();
          QByteArray qba;
          serializeQByteArray(ar, qba);
          if (qba.size()) { 
            qds.writeRawData(qba.data(), qba.size());
          }
        }
      }
      else if (ar.isWrite())
      {         
        QIODevice * dev = qds.device();
        if (dev->isReadable())             // QIODevice::ReadOnly
        {
          boost::uint32_t count = dev->bytesAvailable();
          if (count == 0)
          {
            ar & count;
          }
          else
          {
            serializeQByteArray(ar, dev->readAll());
          }
        }  
      }
    }

    // QDateTime    
    inline void serialize(SF::Archive & ar, QDateTime & qdt)
    {
      if (ar.isRead())
      {
        boost::int64_t utc_time;
        serializeFundamental(ar, utc_time);
        qdt.setMSecsSinceEpoch(utc_time);
      }
      else if (ar.isWrite())
      {
        boost::int64_t utc_time = qdt.toMSecsSinceEpoch();
        serializeFundamental(ar, utc_time);
      }
    }
    
    // QPair
    template<typename T, typename U>
    inline void serialize_vc6(Archive &ar, QPair<T,U> &t, const unsigned int)
    {
      ar & t.first & t.second;
    }    
    
} // namespace SF

#endif // ! INCLUDE_SF_QCORE_HPP
Tested only on Windows machines. Therefore, it may require the use RCF::networkToMachineOrder and QDataStream::setByteOrder.

acDev
Posts: 27
Joined: Tue Oct 08, 2013 3:08 pm
Location: Moscow
Contact:

Re: [SF] Serialization Qt classes (with examples)

Post by acDev »


jarl
Posts: 238
Joined: Mon Oct 03, 2011 4:53 am
Contact:

Re: [SF] Serialization Qt classes (with examples)

Post by jarl »

Thanks - we'll drop that into the next release.
Kind Regards

Jarl Lindrud
Delta V Software
http://www.deltavsoft.com

Post Reply