Skip to content

Commit

Permalink
common: Disable enum type stream operators for Qt >= 5.14
Browse files Browse the repository at this point in the history
Starting from version 5.14, Qt provides stream operators for enum
types, which collide with the ones we ship in types.h. Disable
Quassel's stream operators when compiling against Qt 5.14 or later.

Add a unit test that ensures that enum serialization honors the width
of the underlying type.
  • Loading branch information
Sput42 committed Jan 8, 2020
1 parent 73db06f commit 579e559
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/common/types.h
Expand Up @@ -195,6 +195,7 @@ Q_DECLARE_METATYPE(QHostAddress)
using MsgIdList = QList<MsgId>;
using BufferIdList = QList<BufferId>;

#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
/**
* Catch-all stream serialization operator for enum types.
*
Expand Down Expand Up @@ -224,6 +225,7 @@ QDataStream& operator>>(QDataStream& in, T& value)
value = static_cast<T>(v);
return in;
}
#endif

// STL-compliant hash functor for Qt types
template<typename T>
Expand Down
2 changes: 2 additions & 0 deletions tests/common/CMakeLists.txt
Expand Up @@ -11,4 +11,6 @@ quassel_add_test(SignalProxyTest
Quassel::Test::Util
)

quassel_add_test(TypesTest)

quassel_add_test(UtilTest)
79 changes: 79 additions & 0 deletions tests/common/typestest.cpp
@@ -0,0 +1,79 @@
/***************************************************************************
* Copyright (C) 2005-2020 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) version 3. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/

#include <cstdint>

#include <QByteArray>
#include <QDataStream>
#include <QObject>

#include "testglobal.h"
#include "types.h"

using namespace ::testing;

class EnumHolder
{
Q_GADGET

public:
enum class Enum16 : uint16_t {};
enum class Enum32 : uint32_t {};

enum class EnumQt16 : uint16_t {};
Q_ENUM(EnumQt16)
enum class EnumQt32 : uint32_t {};
Q_ENUM(EnumQt32)
};

// Verify that enums are (de)serialized as their underlying type
TEST(TypesTest, enumSerialization)
{
QByteArray data;
QDataStream out(&data, QIODevice::WriteOnly);

// Serialize
out << EnumHolder::Enum16(0xabcd);
ASSERT_THAT(data.size(), Eq(2));
out << EnumHolder::Enum32(0x123456);
ASSERT_THAT(data.size(), Eq(6));
out << EnumHolder::EnumQt16(0x4321);
ASSERT_THAT(data.size(), Eq(8));
out << EnumHolder::Enum32(0xfedcba);
ASSERT_THAT(data.size(), Eq(12));
ASSERT_THAT(out.status(), Eq(QDataStream::Status::Ok));

// Deserialize
QDataStream in(data);
EnumHolder::Enum16 enum16;
EnumHolder::Enum32 enum32;
EnumHolder::EnumQt16 enumQt16;
EnumHolder::EnumQt32 enumQt32;
in >> enum16 >> enum32 >> enumQt16 >> enumQt32;
ASSERT_THAT(in.status(), Eq(QDataStream::Status::Ok));
EXPECT_TRUE(in.atEnd());

EXPECT_THAT((int)enum16, Eq(0xabcd));
EXPECT_THAT((int)enum32, Eq(0x123456));
EXPECT_THAT((int)enumQt16, Eq(0x4321));
EXPECT_THAT((int)enumQt32, Eq(0xfedcba));
}

#include "typestest.moc"

0 comments on commit 579e559

Please sign in to comment.