132 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "NetworkMessage.hpp"
 | |
| 
 | |
| #include <exception>
 | |
| 
 | |
| #include <QString>
 | |
| #include <QByteArray>
 | |
| 
 | |
| #include "pimpl_impl.hpp"
 | |
| 
 | |
| namespace NetworkMessage
 | |
| {
 | |
|   Builder::Builder (QIODevice * device, Type type, QString const& id, quint32 schema)
 | |
|     : QDataStream {device}
 | |
|   {
 | |
|     common_initialization (type, id, schema);
 | |
|   }
 | |
| 
 | |
|   Builder::Builder (QByteArray * a, Type type, QString const& id, quint32 schema)
 | |
|     : QDataStream {a, QIODevice::WriteOnly}
 | |
|   {
 | |
|     common_initialization (type, id, schema);
 | |
|   }
 | |
| 
 | |
|   void Builder::common_initialization (Type type, QString const& id, quint32 schema)
 | |
|   {
 | |
|     if (schema <= 1)
 | |
|       {
 | |
|         setVersion (QDataStream::Qt_5_0); // Qt schema version
 | |
|       }
 | |
| #if QT_VERSION >= 0x050200
 | |
|     else if (schema <= 2)
 | |
|       {
 | |
|         setVersion (QDataStream::Qt_5_2); // Qt schema version
 | |
|       }
 | |
| #endif
 | |
| #if QT_VERSION >= 0x050400
 | |
|     else if (schema <= 3)
 | |
|       {
 | |
|         setVersion (QDataStream::Qt_5_4); // Qt schema version
 | |
|       }
 | |
| #endif
 | |
|     else
 | |
|       {
 | |
|         throw std::runtime_error {"Unrecognized message schema"};
 | |
|       }
 | |
| 
 | |
|     // the following two items assume that the quint32 encoding is
 | |
|     // unchanged over QDataStream versions
 | |
|     *this << magic;
 | |
|     *this << schema;
 | |
| 
 | |
|     *this << static_cast<quint32> (type) << id.toUtf8 ();
 | |
|   }
 | |
| 
 | |
|   class Reader::impl
 | |
|   {
 | |
|   public:
 | |
|     void common_initialization (Reader * parent)
 | |
|     {
 | |
|       quint32 magic;
 | |
|       *parent >> magic;
 | |
|       if (magic != Builder::magic)
 | |
|         {
 | |
|           throw std::runtime_error {"Invalid message format"};
 | |
|         }
 | |
|       *parent >> schema_;
 | |
|       if (schema_ > Builder::schema_number)
 | |
|         {
 | |
|           throw std::runtime_error {"Unrecognized message schema"};
 | |
|         }
 | |
|       if (schema_ <= 1)
 | |
|         {
 | |
|           parent->setVersion (QDataStream::Qt_5_0);
 | |
|         }
 | |
| #if QT_VERSION >= 0x050200
 | |
|       else if (schema_ <= 2)
 | |
|         {
 | |
|           parent->setVersion (QDataStream::Qt_5_2);
 | |
|         }
 | |
| #endif
 | |
| #if QT_VERSION >= 0x050400
 | |
|       else if (schema_ <= 3)
 | |
|         {
 | |
|           parent->setVersion (QDataStream::Qt_5_4);
 | |
|         }
 | |
| #endif
 | |
|       quint32 type;
 | |
|       *parent >> type >> id_;
 | |
|       if (type >= maximum_message_type_)
 | |
|         {
 | |
|           throw std::runtime_error {"Unrecognized message type"};
 | |
|         }
 | |
|       type_ = static_cast<Type> (type);
 | |
|     }
 | |
| 
 | |
|     quint32 schema_;
 | |
|     Type type_;
 | |
|     QByteArray id_;
 | |
|   };
 | |
| 
 | |
|   Reader::Reader (QIODevice * device)
 | |
|     : QDataStream {device}
 | |
|   {
 | |
|     m_->common_initialization (this);
 | |
|   }
 | |
| 
 | |
|   Reader::Reader (QByteArray const& a)
 | |
|     : QDataStream {a}
 | |
|   {
 | |
|     m_->common_initialization (this);
 | |
|   }
 | |
| 
 | |
|   Reader::~Reader ()
 | |
|   {
 | |
|   }
 | |
| 
 | |
|   quint32 Reader::schema () const
 | |
|   {
 | |
|     return m_->schema_;
 | |
|   }
 | |
| 
 | |
|   Type Reader::type () const
 | |
|   {
 | |
|     return static_cast<Type> (m_->type_);
 | |
|   }
 | |
| 
 | |
|   QString Reader::id () const
 | |
|   {
 | |
|     return QString::fromUtf8 (m_->id_);
 | |
|   }
 | |
| }
 | 
