qtgrpc/src/protobuf/qtprotobuftypes.h

222 lines
7.1 KiB
C++

// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2019 Alexey Edelev <semlanik@gmail.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTPROTOBUFTYPES_H
#define QTPROTOBUFTYPES_H
#include <QtProtobuf/qtprotobufglobal.h>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QMetaType>
#include <QtCore/QtEndian>
#include <memory>
#include <functional>
#include <list>
#include <type_traits>
#include <utility>
QT_BEGIN_NAMESPACE
namespace QtProtobufPrivate {
enum FieldFlag : uint { NoFlags = 0x0, NonPacked = 0x1 };
struct QProtobufPropertyOrdering
{
const struct Data {
uint version;
uint numFields;
uint fieldNumberOffset;
uint propertyIndexOffset;
uint flagsOffset;
} *data;
Q_PROTOBUF_EXPORT QUtf8StringView getJsonName(int index) const;
Q_PROTOBUF_EXPORT int getFieldNumber(int index) const;
Q_PROTOBUF_EXPORT int getPropertyIndex(int index) const;
Q_PROTOBUF_EXPORT uint getFieldFlags(int index) const;
Q_PROTOBUF_EXPORT int indexOfFieldNumber(int fieldNumber) const;
inline int fieldCount() const { return int(data->numFields); }
private:
const uint *uint_data() const;
const char *char_data() const;
const uint &uint_dataForIndex(int index, uint offset) const;
};
static_assert(std::is_trivially_destructible_v<QProtobufPropertyOrdering>);
// Convenience structure to hold a reference to a single entry
struct QProtobufPropertyOrderingInfo
{
inline QProtobufPropertyOrderingInfo(QProtobufPropertyOrdering ord, int ind)
: ordering(ord), index(ind)
{
Q_ASSERT(index >= 0);
}
inline QUtf8StringView getJsonName() const { return ordering.getJsonName(index); }
inline int getFieldNumber() const
{
return (overrideFieldNumber >= 0) ? overrideFieldNumber : ordering.getFieldNumber(index);
}
inline int getPropertyIndex() const { return ordering.getPropertyIndex(index); }
inline uint getFieldFlags() const { return ordering.getFieldFlags(index); }
// Needed for maps, which uses field number 1 and 2 for key and value respectively
QProtobufPropertyOrderingInfo infoForMapKey() const { return { ordering, index, 1 }; }
QProtobufPropertyOrderingInfo infoForMapValue() const { return { ordering, index, 2 }; }
private:
inline QProtobufPropertyOrderingInfo(QProtobufPropertyOrdering ord, int ind, int fieldNumber)
: ordering(ord), index(ind), overrideFieldNumber(fieldNumber)
{
}
const QProtobufPropertyOrdering ordering;
const int index;
const int overrideFieldNumber = -1; // special case for maps
};
template<typename>
using sfinae = void;
template<typename T, typename = void>
[[maybe_unused]]
static constexpr bool HasProtobufPropertyOrdering = false;
template<typename T>
[[maybe_unused]]
static constexpr bool HasProtobufPropertyOrdering<T, sfinae<decltype(T::propertyOrdering)>> = true;
} // namespace QtProtobufPrivate
namespace QtProtobuf {
Q_NAMESPACE_EXPORT(Q_PROTOBUF_EXPORT)
enum class WireTypes
{
Unknown = -1,
Varint = 0,
Fixed64 = 1,
LengthDelimited = 2,
StartGroup = 3,
EndGroup = 4,
Fixed32 = 5
};
Q_ENUM_NS(WireTypes)
// The 'tag' template param exists only create a unique type
template<typename T, typename tag>
struct TransparentWrapper {
TransparentWrapper(T t = T()) : _t(t) {}
T _t;
operator T &() { return _t; }
operator T() const { return _t; }
TransparentWrapper &operator =(const T &t) { _t = t; return *this; }
static T toType(TransparentWrapper t) { return t._t; }
static TransparentWrapper fromType(T _t) { return TransparentWrapper(_t); }
static QString toString(TransparentWrapper t) { return QString::number(t._t); }
};
template<typename T, typename tag>
constexpr TransparentWrapper<T, tag> qbswap(TransparentWrapper<T, tag> source)
{
return { QT_PREPEND_NAMESPACE(qbswap)(source._t) };
}
using int32 = TransparentWrapper<int32_t, struct int_tag>;
using int64 = TransparentWrapper<int64_t, struct int_tag>;
using uint32 = uint32_t;
using uint64 = uint64_t;
using sint32 = int32_t;
using sint64 = int64_t;
using fixed32 = TransparentWrapper<uint32_t, struct fixed_tag>;
using fixed64 = TransparentWrapper<uint64_t, struct fixed_tag>;
using sfixed32 = TransparentWrapper<int32_t, struct fixed_tag>;
using sfixed64 = TransparentWrapper<int64_t, struct fixed_tag>;
using boolean = bool;
using int32List = QList<int32>;
using int64List = QList<int64>;
using uint32List = QList<uint32>;
using uint64List = QList<uint64>;
using sint32List = QList<sint32>;
using sint64List = QList<sint64>;
using fixed32List = QList<fixed32>;
using fixed64List = QList<fixed64>;
using sfixed32List = QList<sfixed32>;
using sfixed64List = QList<sfixed64>;
using floatList = QList<float>;
using doubleList = QList<double>;
using boolList = QList<bool>;
using RegisterFunction = void(*)();
// This struct is used for type registrations in generated code
struct ProtoTypeRegistrar
{
Q_PROTOBUF_EXPORT explicit ProtoTypeRegistrar(QtProtobuf::RegisterFunction initializer);
};
template<typename T>
bool repeatedValueCompare(const QList<std::shared_ptr<T>> &a, const QList<std::shared_ptr<T>> &b)
{
auto dereferenced = [](const std::shared_ptr<T> &lhs, const std::shared_ptr<T> &rhs) {
return lhs == rhs || (lhs && rhs && *lhs == *rhs);
};
return std::equal(a.begin(), a.end(), b.begin(), b.end(), dereferenced);
}
template<typename K, typename V>
bool repeatedValueCompare(const QHash<K, V> &a, const QHash<K, V> &b)
{
return a == b;
}
template<typename K, typename V>
bool repeatedValueCompare(const QHash<K, std::shared_ptr<V>> &a,
const QHash<K, std::shared_ptr<V>> &b)
{
if (a.size() != b.size())
return false;
for (auto itA = a.constBegin(); itA != a.constEnd(); ++itA) {
auto itB = b.constFind(itA.key());
if (itB == b.constEnd() || (itA.value() != itB.value() && *(itA.value()) != *(itB.value())))
return false;
}
return true;
}
template <typename T>
struct qMakeUnsignedImpl {
using type = std::make_unsigned_t<T>;
};
template<typename T>
struct qMakeUnsignedImpl<TransparentWrapper<T, struct fixed_tag>> {
using type = TransparentWrapper<std::make_unsigned_t<T>, fixed_tag>;
};
template<>
struct qMakeUnsignedImpl<int32> {
using type = uint32_t;
};
template<>
struct qMakeUnsignedImpl<int64> {
using type = uint64_t;
};
template <typename T>
using qMakeUnsigned = typename qMakeUnsignedImpl<T>::type;
} //namespace QtProtobuf
Q_PROTOBUF_EXPORT void qRegisterProtobufTypes();
QT_END_NAMESPACE
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::int32, QtProtobuf_int32, Q_PROTOBUF_EXPORT)
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::int64, QtProtobuf_int64, Q_PROTOBUF_EXPORT)
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::fixed32, QtProtobuf_fixed32, Q_PROTOBUF_EXPORT)
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::fixed64, QtProtobuf_fixed64, Q_PROTOBUF_EXPORT)
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::sfixed32, QtProtobuf_sfixed32, Q_PROTOBUF_EXPORT)
QT_DECL_METATYPE_EXTERN_TAGGED(QtProtobuf::sfixed64, QtProtobuf_sfixed64, Q_PROTOBUF_EXPORT)
#endif // QTPROTOBUFTYPES_H