mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 17:35:34 +08:00
Ref T552 Added mixins for QDataStream marshalling.
This commit is contained in:
133
src/blackmisc/datastream.h
Normal file
133
src/blackmisc/datastream.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2019
|
||||
* swift Project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
||||
* or distributed except according to the terms contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKMISC_DATASTREAM_H
|
||||
#define BLACKMISC_DATASTREAM_H
|
||||
|
||||
#include "blackmisc/typetraits.h"
|
||||
#include <QDataStream>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CEmpty;
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
/*!
|
||||
* CRTP class template to generate non-member QDataStream streaming operators.
|
||||
*
|
||||
* \tparam Derived Must implement public methods marshalToDataStream(QDataStream &) and unmarshalFromDataStream(QDataStream &).
|
||||
*/
|
||||
template <class Derived>
|
||||
class DataStreamOperators
|
||||
{
|
||||
public:
|
||||
//! Marshal a value to a QDataStream.
|
||||
friend QDataStream &operator <<(QDataStream &stream, const Derived &value)
|
||||
{
|
||||
value.marshalToDataStream(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
//! Unmarshal a value from a QDataStream.
|
||||
friend QDataStream &operator >>(QDataStream &stream, Derived &value)
|
||||
{
|
||||
value.unmarshalFromDataStream(stream);
|
||||
return stream;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* CRTP class template to generate QDataStream marshalling methods using CMetaClass.
|
||||
*
|
||||
* \see BLACKMISC_DECLARE_USING_MIXIN_DATASTREAM
|
||||
*/
|
||||
template <class Derived>
|
||||
class DataStreamByMetaClass : public DataStreamOperators<Derived>
|
||||
{
|
||||
public:
|
||||
//! Marshal a value to a QDataStream.
|
||||
void marshalToDataStream(QDataStream &stream) const
|
||||
{
|
||||
baseMarshal(static_cast<const TBaseOfT<Derived> *>(derived()), stream);
|
||||
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember([ &, this ](auto member) { stream << member.in(*this->derived()); });
|
||||
}
|
||||
|
||||
//! Unmarshal a value from a QDataStream.
|
||||
void unmarshalFromDataStream(QDataStream &stream)
|
||||
{
|
||||
baseUnmarshal(static_cast<TBaseOfT<Derived> *>(derived()), stream);
|
||||
constexpr auto meta = introspect<Derived>().without(MetaFlags<DisabledForMarshalling>());
|
||||
meta.forEachMember([ &, this ](auto member) { stream >> member.in(*this->derived()); });
|
||||
}
|
||||
|
||||
private:
|
||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||
Derived *derived() { return static_cast<Derived *>(this); }
|
||||
|
||||
template <typename T> static void baseMarshal(const T *base, QDataStream &stream) { base->marshalToDataStream(stream); }
|
||||
template <typename T> static void baseUnmarshal(T *base, QDataStream &stream) { base->unmarshalFromDataStream(stream); }
|
||||
static void baseMarshal(const void *, QDataStream &) {}
|
||||
static void baseUnmarshal(void *, QDataStream &) {}
|
||||
static void baseMarshal(const CEmpty *, QDataStream &) {}
|
||||
static void baseUnmarshal(CEmpty *, QDataStream &) {}
|
||||
};
|
||||
|
||||
/*!
|
||||
* When a derived class and a base class both inherit from Mixin::DataStreamByMetaClass,
|
||||
* the derived class uses this macro to disambiguate the inherited members.
|
||||
*/
|
||||
# define BLACKMISC_DECLARE_USING_MIXIN_DATASTREAM(DERIVED) \
|
||||
using ::BlackMisc::Mixin::DataStreamByMetaClass<DERIVED>::marshalToDataStream; \
|
||||
using ::BlackMisc::Mixin::DataStreamByMetaClass<DERIVED>::unmarshalFromDataStream;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Operator for marshalling enums with QDataStream.
|
||||
*/
|
||||
template <typename E, typename = std::enable_if_t<std::is_enum<E>::value>>
|
||||
QDataStream &operator <<(QDataStream &stream, E value)
|
||||
{
|
||||
return stream << static_cast<int>(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Operator for unmarshalling enums with QDataStream.
|
||||
*/
|
||||
template <typename E, typename = std::enable_if_t<std::is_enum<E>::value>>
|
||||
QDataStream &operator >>(QDataStream &stream, E &value)
|
||||
{
|
||||
int temp;
|
||||
stream >> temp;
|
||||
value = static_cast<E>(temp);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Operator for marshalling pairs with QDataStream.
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
QDataStream &operator <<(QDataStream &stream, const std::pair<T, U> &pair)
|
||||
{
|
||||
return stream << pair.first << pair.second;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Operator for unmarshalling pairs with QDataStream.
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
QDataStream &operator >>(QDataStream &stream, std::pair<T, U> &pair)
|
||||
{
|
||||
return stream >> pair.first >> pair.second;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -182,7 +182,7 @@ namespace BlackMisc
|
||||
enum MetaFlag
|
||||
{
|
||||
DisabledForComparison = 1 << 0, //!< Element will be ignored by compare() and comparison operators
|
||||
DisabledForMarshalling = 1 << 1, //!< Element will be ignored during DBus marshalling
|
||||
DisabledForMarshalling = 1 << 1, //!< Element will be ignored during DBus and QDataStream marshalling
|
||||
DisabledForDebugging = 1 << 2, //!< Element will be ignored when streaming to QDebug
|
||||
DisabledForHashing = 1 << 3, //!< Element will be ignored by qHash()
|
||||
DisabledForJson = 1 << 4, //!< Element will be ignored during JSON serialization
|
||||
|
||||
Reference in New Issue
Block a user