mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-09 13:12:40 +02:00
More enum stuff, with tests.
This commit is contained in:
parent
a4aa5eb4e8
commit
54a5bc3a49
4 changed files with 250 additions and 55 deletions
|
@ -71,6 +71,10 @@ IDStreamer& IDStreamer::operator>>(int& value) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
static QByteArray getEnumName(const QMetaEnum& metaEnum) {
|
||||
return QByteArray(metaEnum.scope()) + "::" + metaEnum.name();
|
||||
}
|
||||
|
||||
int Bitstream::registerMetaObject(const char* className, const QMetaObject* metaObject) {
|
||||
getMetaObjects().insert(className, metaObject);
|
||||
|
||||
|
@ -84,12 +88,7 @@ int Bitstream::registerMetaObject(const char* className, const QMetaObject* meta
|
|||
QMetaEnum metaEnum = metaObject->enumerator(i);
|
||||
const TypeStreamer*& streamer = getEnumStreamers()[QPair<QByteArray, QByteArray>(metaEnum.scope(), metaEnum.name())];
|
||||
if (!streamer) {
|
||||
int highestValue = 0;
|
||||
for (int j = 0; j < metaEnum.keyCount(); j++) {
|
||||
highestValue = qMax(highestValue, metaEnum.value(j));
|
||||
}
|
||||
streamer = new EnumTypeStreamer(QByteArray(metaEnum.scope()) + "::" + metaEnum.name(),
|
||||
highestValue == 0 ? 0 : 1 + (int)(log(highestValue) / log(2.0)));
|
||||
getEnumStreamersByName().insert(getEnumName(metaEnum), streamer = new EnumTypeStreamer(metaEnum));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +134,14 @@ void Bitstream::addTypeSubstitution(const QByteArray& typeName, int type) {
|
|||
_typeStreamerSubstitutions.insert(typeName, getTypeStreamers().value(type));
|
||||
}
|
||||
|
||||
void Bitstream::addTypeSubstitution(const QByteArray& typeName, const char* replacementTypeName) {
|
||||
const TypeStreamer* streamer = getTypeStreamers().value(QMetaType::type(replacementTypeName));
|
||||
if (!streamer) {
|
||||
streamer = getEnumStreamersByName().value(replacementTypeName);
|
||||
}
|
||||
_typeStreamerSubstitutions.insert(typeName, streamer);
|
||||
}
|
||||
|
||||
const int LAST_BIT_POSITION = BITS_IN_BYTE - 1;
|
||||
|
||||
Bitstream& Bitstream::write(const void* data, int bits, int offset) {
|
||||
|
@ -659,9 +666,27 @@ Bitstream& Bitstream::operator<(const TypeStreamer* streamer) {
|
|||
case TypeReader::SIMPLE_TYPE:
|
||||
return *this;
|
||||
|
||||
case TypeReader::ENUM_TYPE:
|
||||
return *this << streamer->getBits();
|
||||
|
||||
case TypeReader::ENUM_TYPE: {
|
||||
QMetaEnum metaEnum = streamer->getMetaEnum();
|
||||
if (_metadataType == FULL_METADATA) {
|
||||
*this << metaEnum.keyCount();
|
||||
for (int i = 0; i < metaEnum.keyCount(); i++) {
|
||||
*this << QByteArray::fromRawData(metaEnum.key(i), strlen(metaEnum.key(i)));
|
||||
*this << metaEnum.value(i);
|
||||
}
|
||||
} else {
|
||||
*this << streamer->getBits();
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
for (int i = 0; i < metaEnum.keyCount(); i++) {
|
||||
hash.addData(metaEnum.key(i), strlen(metaEnum.key(i)) + 1);
|
||||
qint32 value = metaEnum.value(i);
|
||||
hash.addData((const char*)&value, sizeof(qint32));
|
||||
}
|
||||
QByteArray hashResult = hash.result();
|
||||
write(hashResult.constData(), hashResult.size() * BITS_IN_BYTE);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
case TypeReader::LIST_TYPE:
|
||||
case TypeReader::SET_TYPE:
|
||||
return *this << streamer->getValueStreamer();
|
||||
|
@ -694,6 +719,10 @@ Bitstream& Bitstream::operator<(const TypeStreamer* streamer) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
static int getBitsForHighestValue(int highestValue) {
|
||||
return (highestValue == 0) ? 0 : 1 + (int)(log(highestValue) / log(2.0));
|
||||
}
|
||||
|
||||
Bitstream& Bitstream::operator>(TypeReader& reader) {
|
||||
QByteArray typeName;
|
||||
*this >> typeName;
|
||||
|
@ -703,14 +732,9 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
|||
}
|
||||
const TypeStreamer* streamer = _typeStreamerSubstitutions.value(typeName);
|
||||
if (!streamer) {
|
||||
int index = typeName.indexOf("::");
|
||||
if (index == -1) {
|
||||
streamer = getTypeStreamers().value(QMetaType::type(typeName.constData()));
|
||||
} else {
|
||||
int postIndex = index + 2;
|
||||
streamer = getEnumStreamers().value(QPair<QByteArray, QByteArray>(
|
||||
QByteArray::fromRawData(typeName.constData(), index),
|
||||
QByteArray::fromRawData(typeName.constData() + postIndex, typeName.size() - postIndex)));
|
||||
streamer = getTypeStreamers().value(QMetaType::type(typeName.constData()));
|
||||
if (!streamer) {
|
||||
streamer = getEnumStreamersByName().value(typeName);
|
||||
}
|
||||
}
|
||||
if (!streamer) {
|
||||
|
@ -728,12 +752,50 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
|||
return *this;
|
||||
|
||||
case TypeReader::ENUM_TYPE: {
|
||||
int bits;
|
||||
*this >> bits;
|
||||
if (streamer && streamer->getReaderType() == type) {
|
||||
reader = TypeReader(typeName, streamer);
|
||||
if (_metadataType == FULL_METADATA) {
|
||||
int keyCount;
|
||||
*this >> keyCount;
|
||||
QMetaEnum metaEnum = (streamer && streamer->getReaderType() == TypeReader::ENUM_TYPE) ?
|
||||
streamer->getMetaEnum() : QMetaEnum();
|
||||
QHash<int, int> mappings;
|
||||
bool matches = (keyCount == metaEnum.keyCount());
|
||||
int highestValue = 0;
|
||||
for (int i = 0; i < keyCount; i++) {
|
||||
QByteArray key;
|
||||
int value;
|
||||
*this >> key >> value;
|
||||
highestValue = qMax(value, highestValue);
|
||||
int localValue = metaEnum.keyToValue(key);
|
||||
if (localValue != -1) {
|
||||
mappings.insert(value, localValue);
|
||||
}
|
||||
matches &= (value == localValue);
|
||||
}
|
||||
if (matches) {
|
||||
reader = TypeReader(typeName, streamer);
|
||||
} else {
|
||||
reader = TypeReader(typeName, streamer, getBitsForHighestValue(highestValue), mappings);
|
||||
}
|
||||
} else {
|
||||
reader = TypeReader(typeName, streamer, false, TypeReader::ENUM_TYPE, bits);
|
||||
int bits;
|
||||
*this >> bits;
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
if (streamer && streamer->getReaderType() == TypeReader::ENUM_TYPE) {
|
||||
QMetaEnum metaEnum = streamer->getMetaEnum();
|
||||
for (int i = 0; i < metaEnum.keyCount(); i++) {
|
||||
hash.addData(metaEnum.key(i), strlen(metaEnum.key(i)) + 1);
|
||||
qint32 value = metaEnum.value(i);
|
||||
hash.addData((const char*)&value, sizeof(qint32));
|
||||
}
|
||||
}
|
||||
QByteArray localHashResult = hash.result();
|
||||
QByteArray remoteHashResult(localHashResult.size(), 0);
|
||||
read(remoteHashResult.data(), remoteHashResult.size() * BITS_IN_BYTE);
|
||||
if (localHashResult == remoteHashResult) {
|
||||
reader = TypeReader(typeName, streamer);
|
||||
} else {
|
||||
reader = TypeReader(typeName, streamer, bits, QHash<int, int>());
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -745,7 +807,7 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
|||
valueReader.matchesExactly(streamer->getValueStreamer())) {
|
||||
reader = TypeReader(typeName, streamer);
|
||||
} else {
|
||||
reader = TypeReader(typeName, streamer, false, (TypeReader::Type)type, 0, TypeReaderPointer(),
|
||||
reader = TypeReader(typeName, streamer, (TypeReader::Type)type,
|
||||
TypeReaderPointer(new TypeReader(valueReader)));
|
||||
}
|
||||
return *this;
|
||||
|
@ -758,8 +820,8 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
|||
valueReader.matchesExactly(streamer->getValueStreamer())) {
|
||||
reader = TypeReader(typeName, streamer);
|
||||
} else {
|
||||
reader = TypeReader(typeName, streamer, false, TypeReader::MAP_TYPE, 0,
|
||||
TypeReaderPointer(new TypeReader(keyReader)), TypeReaderPointer(new TypeReader(valueReader)));
|
||||
reader = TypeReader(typeName, streamer, TypeReaderPointer(new TypeReader(keyReader)),
|
||||
TypeReaderPointer(new TypeReader(valueReader)));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -817,23 +879,20 @@ Bitstream& Bitstream::operator>(TypeReader& reader) {
|
|||
// if all fields are the same type and in the right order, we can use the (more efficient) default streamer
|
||||
const QVector<MetaField>& localFields = streamer->getMetaFields();
|
||||
if (fieldCount != localFields.size()) {
|
||||
reader = TypeReader(typeName, streamer, false, TypeReader::STREAMABLE_TYPE,
|
||||
0, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||
reader = TypeReader(typeName, streamer, fields);
|
||||
return *this;
|
||||
}
|
||||
for (int i = 0; i < fieldCount; i++) {
|
||||
const FieldReader& fieldReader = fields.at(i);
|
||||
if (!fieldReader.getReader().matchesExactly(localFields.at(i).getStreamer()) || fieldReader.getIndex() != i) {
|
||||
reader = TypeReader(typeName, streamer, false, TypeReader::STREAMABLE_TYPE,
|
||||
0, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||
reader = TypeReader(typeName, streamer, fields);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
reader = TypeReader(typeName, streamer);
|
||||
return *this;
|
||||
}
|
||||
reader = TypeReader(typeName, streamer, false, TypeReader::STREAMABLE_TYPE,
|
||||
0, TypeReaderPointer(), TypeReaderPointer(), fields);
|
||||
reader = TypeReader(typeName, streamer, fields);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -969,6 +1028,11 @@ QHash<QPair<QByteArray, QByteArray>, const TypeStreamer*>& Bitstream::getEnumStr
|
|||
return enumStreamers;
|
||||
}
|
||||
|
||||
QHash<QByteArray, const TypeStreamer*>& Bitstream::getEnumStreamersByName() {
|
||||
static QHash<QByteArray, const TypeStreamer*> enumStreamersByName;
|
||||
return enumStreamersByName;
|
||||
}
|
||||
|
||||
QVector<PropertyReader> Bitstream::getPropertyReaders(const QMetaObject* metaObject) {
|
||||
QVector<PropertyReader> propertyReaders;
|
||||
if (!metaObject) {
|
||||
|
@ -995,24 +1059,62 @@ QVector<PropertyReader> Bitstream::getPropertyReaders(const QMetaObject* metaObj
|
|||
return propertyReaders;
|
||||
}
|
||||
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, bool exactMatch, Type type, int bits,
|
||||
const TypeReaderPointer& keyReader, const TypeReaderPointer& valueReader, const QVector<FieldReader>& fields) :
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer) :
|
||||
_typeName(typeName),
|
||||
_streamer(streamer),
|
||||
_exactMatch(exactMatch),
|
||||
_type(type),
|
||||
_exactMatch(true) {
|
||||
}
|
||||
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, int bits, const QHash<int, int>& mappings) :
|
||||
_typeName(typeName),
|
||||
_streamer(streamer),
|
||||
_exactMatch(false),
|
||||
_type(ENUM_TYPE),
|
||||
_bits(bits),
|
||||
_keyReader(keyReader),
|
||||
_valueReader(valueReader),
|
||||
_mappings(mappings) {
|
||||
}
|
||||
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, const QVector<FieldReader>& fields) :
|
||||
_typeName(typeName),
|
||||
_streamer(streamer),
|
||||
_exactMatch(false),
|
||||
_type(STREAMABLE_TYPE),
|
||||
_fields(fields) {
|
||||
}
|
||||
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer,
|
||||
Type type, const TypeReaderPointer& valueReader) :
|
||||
_typeName(typeName),
|
||||
_streamer(streamer),
|
||||
_exactMatch(false),
|
||||
_type(type),
|
||||
_valueReader(valueReader) {
|
||||
}
|
||||
|
||||
TypeReader::TypeReader(const QByteArray& typeName, const TypeStreamer* streamer,
|
||||
const TypeReaderPointer& keyReader, const TypeReaderPointer& valueReader) :
|
||||
_typeName(typeName),
|
||||
_streamer(streamer),
|
||||
_exactMatch(false),
|
||||
_type(MAP_TYPE),
|
||||
_keyReader(keyReader),
|
||||
_valueReader(valueReader) {
|
||||
}
|
||||
|
||||
QVariant TypeReader::read(Bitstream& in) const {
|
||||
if (_exactMatch) {
|
||||
return _streamer->read(in);
|
||||
}
|
||||
QVariant object = _streamer ? QVariant(_streamer->getType(), 0) : QVariant();
|
||||
switch (_type) {
|
||||
case ENUM_TYPE: {
|
||||
int value = 0;
|
||||
in.read(&value, _bits);
|
||||
if (_streamer) {
|
||||
_streamer->setEnumValue(object, value, _mappings);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STREAMABLE_TYPE: {
|
||||
foreach (const FieldReader& field, _fields) {
|
||||
field.read(in, _streamer, object);
|
||||
|
@ -1069,6 +1171,14 @@ void TypeReader::readRawDelta(Bitstream& in, QVariant& object, const QVariant& r
|
|||
return;
|
||||
}
|
||||
switch (_type) {
|
||||
case ENUM_TYPE: {
|
||||
int value = 0;
|
||||
in.read(&value, _bits);
|
||||
if (_streamer) {
|
||||
_streamer->setEnumValue(object, value, _mappings);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STREAMABLE_TYPE: {
|
||||
foreach (const FieldReader& field, _fields) {
|
||||
field.readDelta(in, _streamer, object, reference);
|
||||
|
@ -1269,6 +1379,10 @@ const char* TypeStreamer::getName() const {
|
|||
return QMetaType::typeName(_type);
|
||||
}
|
||||
|
||||
void TypeStreamer::setEnumValue(QVariant& object, int value, const QHash<int, int>& mappings) const {
|
||||
// nothing by default
|
||||
}
|
||||
|
||||
const QVector<MetaField>& TypeStreamer::getMetaFields() const {
|
||||
static QVector<MetaField> emptyMetaFields;
|
||||
return emptyMetaFields;
|
||||
|
@ -1294,6 +1408,10 @@ int TypeStreamer::getBits() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
QMetaEnum TypeStreamer::getMetaEnum() const {
|
||||
return QMetaEnum();
|
||||
}
|
||||
|
||||
const TypeStreamer* TypeStreamer::getKeyStreamer() const {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1338,9 +1456,17 @@ QDebug& operator<<(QDebug& debug, const QMetaObject* metaObject) {
|
|||
return debug << (metaObject ? metaObject->className() : "null");
|
||||
}
|
||||
|
||||
EnumTypeStreamer::EnumTypeStreamer(const QByteArray& name, int bits) :
|
||||
_name(name),
|
||||
_bits(bits) {
|
||||
EnumTypeStreamer::EnumTypeStreamer(const QMetaEnum& metaEnum) :
|
||||
_metaEnum(metaEnum),
|
||||
_name(getEnumName(metaEnum)) {
|
||||
|
||||
setType(QMetaType::Int);
|
||||
|
||||
int highestValue = 0;
|
||||
for (int j = 0; j < metaEnum.keyCount(); j++) {
|
||||
highestValue = qMax(highestValue, metaEnum.value(j));
|
||||
}
|
||||
_bits = getBitsForHighestValue(highestValue);
|
||||
}
|
||||
|
||||
const char* EnumTypeStreamer::getName() const {
|
||||
|
@ -1355,6 +1481,10 @@ int EnumTypeStreamer::getBits() const {
|
|||
return _bits;
|
||||
}
|
||||
|
||||
QMetaEnum EnumTypeStreamer::getMetaEnum() const {
|
||||
return _metaEnum;
|
||||
}
|
||||
|
||||
bool EnumTypeStreamer::equal(const QVariant& first, const QVariant& second) const {
|
||||
return first.toInt() == second.toInt();
|
||||
}
|
||||
|
@ -1403,3 +1533,18 @@ void EnumTypeStreamer::readRawDelta(Bitstream& in, QVariant& value, const QVaria
|
|||
value = intValue;
|
||||
}
|
||||
|
||||
void EnumTypeStreamer::setEnumValue(QVariant& object, int value, const QHash<int, int>& mappings) const {
|
||||
if (_metaEnum.isFlag()) {
|
||||
int combined = 0;
|
||||
for (QHash<int, int>::const_iterator it = mappings.constBegin(); it != mappings.constEnd(); it++) {
|
||||
if (value & it.key()) {
|
||||
combined |= it.value();
|
||||
}
|
||||
}
|
||||
object = combined;
|
||||
|
||||
} else {
|
||||
object = mappings.value(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -236,6 +236,9 @@ public:
|
|||
/// Substitutes the supplied type for the given type name's default mapping.
|
||||
void addTypeSubstitution(const QByteArray& typeName, int type);
|
||||
|
||||
/// Substitutes the named type for the given type name's default mapping.
|
||||
void addTypeSubstitution(const QByteArray& typeName, const char* replacementTypeName);
|
||||
|
||||
/// Writes a set of bits to the underlying stream.
|
||||
/// \param bits the number of bits to write
|
||||
/// \param offset the offset of the first bit
|
||||
|
@ -424,6 +427,7 @@ private:
|
|||
static QMultiHash<const QMetaObject*, const QMetaObject*>& getMetaObjectSubClasses();
|
||||
static QHash<int, const TypeStreamer*>& getTypeStreamers();
|
||||
static QHash<QPair<QByteArray, QByteArray>, const TypeStreamer*>& getEnumStreamers();
|
||||
static QHash<QByteArray, const TypeStreamer*>& getEnumStreamersByName();
|
||||
static QVector<PropertyReader> getPropertyReaders(const QMetaObject* metaObject);
|
||||
};
|
||||
|
||||
|
@ -716,11 +720,18 @@ public:
|
|||
|
||||
enum Type { SIMPLE_TYPE, ENUM_TYPE, STREAMABLE_TYPE, LIST_TYPE, SET_TYPE, MAP_TYPE };
|
||||
|
||||
TypeReader(const QByteArray& typeName = QByteArray(), const TypeStreamer* streamer = NULL, bool exactMatch = true,
|
||||
Type type = SIMPLE_TYPE, int bits = 0, const TypeReaderPointer& keyReader = TypeReaderPointer(),
|
||||
const TypeReaderPointer& valueReader = TypeReaderPointer(),
|
||||
const QVector<FieldReader>& fields = QVector<FieldReader>());
|
||||
TypeReader(const QByteArray& typeName = QByteArray(), const TypeStreamer* streamer = NULL);
|
||||
|
||||
TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, int bits, const QHash<int, int>& mappings);
|
||||
|
||||
TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, const QVector<FieldReader>& fields);
|
||||
|
||||
TypeReader(const QByteArray& typeName, const TypeStreamer* streamer, Type type,
|
||||
const TypeReaderPointer& valueReader);
|
||||
|
||||
TypeReader(const QByteArray& typeName, const TypeStreamer* streamer,
|
||||
const TypeReaderPointer& keyReader, const TypeReaderPointer& valueReader);
|
||||
|
||||
const QByteArray& getTypeName() const { return _typeName; }
|
||||
const TypeStreamer* getStreamer() const { return _streamer; }
|
||||
|
||||
|
@ -740,6 +751,7 @@ private:
|
|||
bool _exactMatch;
|
||||
Type _type;
|
||||
int _bits;
|
||||
QHash<int, int> _mappings;
|
||||
TypeReaderPointer _keyReader;
|
||||
TypeReaderPointer _valueReader;
|
||||
QVector<FieldReader> _fields;
|
||||
|
@ -871,6 +883,8 @@ public:
|
|||
virtual void writeRawDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const = 0;
|
||||
virtual void readRawDelta(Bitstream& in, QVariant& value, const QVariant& reference) const = 0;
|
||||
|
||||
virtual void setEnumValue(QVariant& object, int value, const QHash<int, int>& mappings) const;
|
||||
|
||||
virtual const QVector<MetaField>& getMetaFields() const;
|
||||
virtual int getFieldIndex(const QByteArray& name) const;
|
||||
virtual void setField(QVariant& object, int index, const QVariant& value) const;
|
||||
|
@ -879,6 +893,7 @@ public:
|
|||
virtual TypeReader::Type getReaderType() const;
|
||||
|
||||
virtual int getBits() const;
|
||||
virtual QMetaEnum getMetaEnum() const;
|
||||
|
||||
virtual const TypeStreamer* getKeyStreamer() const;
|
||||
virtual const TypeStreamer* getValueStreamer() const;
|
||||
|
@ -923,11 +938,12 @@ public:
|
|||
class EnumTypeStreamer : public TypeStreamer {
|
||||
public:
|
||||
|
||||
EnumTypeStreamer(const QByteArray& name, int bits);
|
||||
EnumTypeStreamer(const QMetaEnum& metaEnum);
|
||||
|
||||
virtual const char* getName() const;
|
||||
virtual TypeReader::Type getReaderType() const;
|
||||
virtual int getBits() const;
|
||||
virtual QMetaEnum getMetaEnum() const;
|
||||
virtual bool equal(const QVariant& first, const QVariant& second) const;
|
||||
virtual void write(Bitstream& out, const QVariant& value) const;
|
||||
virtual QVariant read(Bitstream& in) const;
|
||||
|
@ -935,9 +951,11 @@ public:
|
|||
virtual void readDelta(Bitstream& in, QVariant& value, const QVariant& reference) const;
|
||||
virtual void writeRawDelta(Bitstream& out, const QVariant& value, const QVariant& reference) const;
|
||||
virtual void readRawDelta(Bitstream& in, QVariant& value, const QVariant& reference) const;
|
||||
virtual void setEnumValue(QVariant& object, int value, const QHash<int, int>& mappings) const;
|
||||
|
||||
private:
|
||||
|
||||
QMetaEnum _metaEnum;
|
||||
QByteArray _name;
|
||||
int _bits;
|
||||
};
|
||||
|
|
|
@ -87,9 +87,11 @@ static bool testSerialization(Bitstream::MetadataType metadataType) {
|
|||
QByteArray array;
|
||||
QDataStream outStream(&array, QIODevice::WriteOnly);
|
||||
Bitstream out(outStream, metadataType);
|
||||
SharedObjectPointer testObjectWrittenA = new TestSharedObjectA(randFloat(), getRandomTestEnum(), getRandomTestFlags());
|
||||
SharedObjectPointer testObjectWrittenA = new TestSharedObjectA(randFloat(), TestSharedObjectA::SECOND_TEST_ENUM,
|
||||
TestSharedObjectA::TestFlags(TestSharedObjectA::FIRST_TEST_FLAG | TestSharedObjectA::THIRD_TEST_FLAG));
|
||||
out << testObjectWrittenA;
|
||||
SharedObjectPointer testObjectWrittenB = new TestSharedObjectB(randFloat(), createRandomBytes());
|
||||
SharedObjectPointer testObjectWrittenB = new TestSharedObjectB(randFloat(), createRandomBytes(),
|
||||
TestSharedObjectB::THIRD_TEST_ENUM, TestSharedObjectB::SECOND_TEST_FLAG);
|
||||
out << testObjectWrittenB;
|
||||
TestMessageC messageWritten = createRandomMessageC();
|
||||
out << QVariant::fromValue(messageWritten);
|
||||
|
@ -102,6 +104,10 @@ static bool testSerialization(Bitstream::MetadataType metadataType) {
|
|||
in.addMetaObjectSubstitution("TestSharedObjectA", &TestSharedObjectB::staticMetaObject);
|
||||
in.addMetaObjectSubstitution("TestSharedObjectB", &TestSharedObjectA::staticMetaObject);
|
||||
in.addTypeSubstitution("TestMessageC", TestMessageA::Type);
|
||||
in.addTypeSubstitution("TestSharedObjectA::TestEnum", "TestSharedObjectB::TestEnum");
|
||||
in.addTypeSubstitution("TestSharedObjectB::TestEnum", "TestSharedObjectA::TestEnum");
|
||||
in.addTypeSubstitution("TestSharedObjectA::TestFlags", "TestSharedObjectB::TestFlags");
|
||||
in.addTypeSubstitution("TestSharedObjectB::TestFlags", "TestSharedObjectA::TestFlags");
|
||||
SharedObjectPointer testObjectReadA;
|
||||
in >> testObjectReadA;
|
||||
|
||||
|
@ -109,8 +115,11 @@ static bool testSerialization(Bitstream::MetadataType metadataType) {
|
|||
qDebug() << "Wrong class for A" << testObjectReadA << metadataType;
|
||||
return true;
|
||||
}
|
||||
if (metadataType == Bitstream::FULL_METADATA && static_cast<TestSharedObjectA*>(testObjectWrittenA.data())->getFoo() !=
|
||||
static_cast<TestSharedObjectB*>(testObjectReadA.data())->getFoo()) {
|
||||
if (metadataType == Bitstream::FULL_METADATA && (static_cast<TestSharedObjectA*>(testObjectWrittenA.data())->getFoo() !=
|
||||
static_cast<TestSharedObjectB*>(testObjectReadA.data())->getFoo() ||
|
||||
static_cast<TestSharedObjectB*>(testObjectReadA.data())->getBaz() != TestSharedObjectB::SECOND_TEST_ENUM ||
|
||||
static_cast<TestSharedObjectB*>(testObjectReadA.data())->getBong() !=
|
||||
TestSharedObjectB::TestFlags(TestSharedObjectB::FIRST_TEST_FLAG | TestSharedObjectB::THIRD_TEST_FLAG))) {
|
||||
QDebug debug = qDebug() << "Failed to transfer shared field from A to B";
|
||||
testObjectWrittenA->dump(debug);
|
||||
testObjectReadA->dump(debug);
|
||||
|
@ -123,8 +132,10 @@ static bool testSerialization(Bitstream::MetadataType metadataType) {
|
|||
qDebug() << "Wrong class for B" << testObjectReadB << metadataType;
|
||||
return true;
|
||||
}
|
||||
if (metadataType == Bitstream::FULL_METADATA && static_cast<TestSharedObjectB*>(testObjectWrittenB.data())->getFoo() !=
|
||||
static_cast<TestSharedObjectA*>(testObjectReadB.data())->getFoo()) {
|
||||
if (metadataType == Bitstream::FULL_METADATA && (static_cast<TestSharedObjectB*>(testObjectWrittenB.data())->getFoo() !=
|
||||
static_cast<TestSharedObjectA*>(testObjectReadB.data())->getFoo() ||
|
||||
static_cast<TestSharedObjectA*>(testObjectReadB.data())->getBaz() != TestSharedObjectA::THIRD_TEST_ENUM ||
|
||||
static_cast<TestSharedObjectA*>(testObjectReadB.data())->getBong() != TestSharedObjectA::SECOND_TEST_FLAG)) {
|
||||
QDebug debug = qDebug() << "Failed to transfer shared field from B to A";
|
||||
testObjectWrittenB->dump(debug);
|
||||
testObjectReadB->dump(debug);
|
||||
|
@ -433,9 +444,11 @@ void TestSharedObjectA::setFoo(float foo) {
|
|||
}
|
||||
}
|
||||
|
||||
TestSharedObjectB::TestSharedObjectB(float foo, const QByteArray& bar) :
|
||||
TestSharedObjectB::TestSharedObjectB(float foo, const QByteArray& bar, TestEnum baz, TestFlags bong) :
|
||||
_foo(foo),
|
||||
_bar(bar) {
|
||||
_bar(bar),
|
||||
_baz(baz),
|
||||
_bong(bong) {
|
||||
sharedObjectsCreated++;
|
||||
}
|
||||
|
||||
|
|
|
@ -109,12 +109,23 @@ private:
|
|||
/// Another simple shared object.
|
||||
class TestSharedObjectB : public SharedObject {
|
||||
Q_OBJECT
|
||||
Q_ENUMS(TestEnum)
|
||||
Q_FLAGS(TestFlag TestFlags)
|
||||
Q_PROPERTY(float foo READ getFoo WRITE setFoo)
|
||||
Q_PROPERTY(QByteArray bar READ getBar WRITE setBar)
|
||||
|
||||
Q_PROPERTY(TestEnum baz READ getBaz WRITE setBaz)
|
||||
Q_PROPERTY(TestFlags bong READ getBong WRITE setBong)
|
||||
|
||||
public:
|
||||
|
||||
Q_INVOKABLE TestSharedObjectB(float foo = 0.0f, const QByteArray& bar = QByteArray());
|
||||
enum TestEnum { ZEROTH_TEST_ENUM, FIRST_TEST_ENUM, SECOND_TEST_ENUM, THIRD_TEST_ENUM, FOURTH_TEST_ENUM };
|
||||
|
||||
enum TestFlag { NO_TEST_FLAGS = 0x0, ZEROTH_TEST_FLAG = 0x01, FIRST_TEST_FLAG = 0x02,
|
||||
SECOND_TEST_FLAG = 0x04, THIRD_TEST_FLAG = 0x08, FOURTH_TEST_FLAG = 0x10 };
|
||||
Q_DECLARE_FLAGS(TestFlags, TestFlag)
|
||||
|
||||
Q_INVOKABLE TestSharedObjectB(float foo = 0.0f, const QByteArray& bar = QByteArray(),
|
||||
TestEnum baz = FIRST_TEST_ENUM, TestFlags bong = 0);
|
||||
virtual ~TestSharedObjectB();
|
||||
|
||||
void setFoo(float foo) { _foo = foo; }
|
||||
|
@ -123,10 +134,18 @@ public:
|
|||
void setBar(const QByteArray& bar) { _bar = bar; }
|
||||
const QByteArray& getBar() const { return _bar; }
|
||||
|
||||
void setBaz(TestEnum baz) { _baz = baz; }
|
||||
TestEnum getBaz() const { return _baz; }
|
||||
|
||||
void setBong(TestFlags bong) { _bong = bong; }
|
||||
TestFlags getBong() const { return _bong; }
|
||||
|
||||
private:
|
||||
|
||||
float _foo;
|
||||
QByteArray _bar;
|
||||
TestEnum _baz;
|
||||
TestFlags _bong;
|
||||
};
|
||||
|
||||
/// A simple test message.
|
||||
|
|
Loading…
Reference in a new issue