From 10f7eae7a0d44a344d9238b69cb7c0bd10efa8e9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 4 Jun 2014 14:56:13 -0700 Subject: [PATCH] implemented decode --- libraries/shared/src/PropertyFlags.h | 60 +++++++++++++++++++++------- tests/octree/src/OctreeTests.cpp | 28 +++++++++++++ 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index 4c4dc6b386..d19f52a846 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -10,7 +10,6 @@ // // // TODO: -// * implement decode // * iterator to enumerate the set values? #ifndef hifi_PropertyFlags_h @@ -50,7 +49,6 @@ public: bool operator!=(const PropertyFlags& other) const { return _flags != other._flags; } bool operator!() const { return _flags.size() == 0; } - PropertyFlags& operator=(const PropertyFlags& other); PropertyFlags& operator|=(PropertyFlags other); @@ -59,9 +57,6 @@ public: PropertyFlags& operator&=(PropertyFlags other); PropertyFlags& operator&=(Enum flag); - PropertyFlags& operator^=(PropertyFlags other); - PropertyFlags& operator^=(Enum flag); - PropertyFlags& operator+=(PropertyFlags other); PropertyFlags& operator+=(Enum flag); @@ -77,9 +72,6 @@ public: PropertyFlags operator&(PropertyFlags other) const; PropertyFlags operator&(Enum flag) const; - PropertyFlags operator^(PropertyFlags other) const; - PropertyFlags operator^(Enum flag) const; - PropertyFlags operator+(PropertyFlags other) const; PropertyFlags operator+(Enum flag) const; @@ -89,7 +81,13 @@ public: PropertyFlags operator<<(PropertyFlags other) const; PropertyFlags operator<<(Enum flag) const; - + // NOTE: due to the nature of the compact storage of these property flags, and the fact that the upper bound of the + // enum is not know, these operators will only perform their bitwise operations on the set of properties that have + // been previously set + PropertyFlags& operator^=(PropertyFlags other); + PropertyFlags& operator^=(Enum flag); + PropertyFlags operator^(PropertyFlags other) const; + PropertyFlags operator^(Enum flag) const; PropertyFlags operator~() const; void debugDumpBits(); @@ -227,7 +225,45 @@ template inline QByteArray PropertyFlags::encode() { return output; } -template inline void PropertyFlags::decode(const QByteArray& fromEncoded) { +template inline void PropertyFlags::decode(const QByteArray& fromEncodedBytes) { + + clear(); // we are cleared out! + + // first convert the ByteArray into a BitArray... + QBitArray encodedBits; + int bitCount = BITS_PER_BYTE * fromEncodedBytes.count(); + encodedBits.resize(bitCount); + + for(int byte = 0; byte < fromEncodedBytes.count(); byte++) { + char originalByte = fromEncodedBytes.at(byte); + for(int bit = 0; bit < BITS_PER_BYTE; bit++) { + int shiftBy = BITS_PER_BYTE - (bit + 1); + char maskBit = ( 1 << shiftBy); + bool bitValue = originalByte & maskBit; + encodedBits.setBit(byte * BITS_PER_BYTE + bit, bitValue); + } + } + + // next, read the leading bits to determine the correct number of bytes to decode (may not match the QByteArray) + int encodedByteCount = 0; + int bitAt; + for (bitAt = 0; bitAt < bitCount; bitAt++) { + if (encodedBits.at(bitAt)) { + encodedByteCount++; + } else { + break; + } + } + encodedByteCount++; // always at least one byte + int expectedBitCount = encodedByteCount * BITS_PER_BYTE; + + // Now, keep reading... + int flagsStartAt = bitAt + 1; + for (bitAt = flagsStartAt; bitAt < expectedBitCount; bitAt++) { + if (encodedBits.at(bitAt)) { + setHasProperty((Enum)(bitAt - flagsStartAt)); + } + } } template inline void PropertyFlags::debugDumpBits() { @@ -431,10 +467,6 @@ BitArr.resize(8*byteArr.count()); for(int i=0; i diff --git a/tests/octree/src/OctreeTests.cpp b/tests/octree/src/OctreeTests.cpp index 7143e6ca7a..d15b77a53a 100644 --- a/tests/octree/src/OctreeTests.cpp +++ b/tests/octree/src/OctreeTests.cpp @@ -367,6 +367,34 @@ void OctreeTests::propertyFlagsTests() { qDebug() << "propsC... encoded="; outputBufferBits((const unsigned char*)encoded.constData(), encoded.size()); } + + { + qDebug() << "Test 8: ParticlePropertyFlags: decode tests"; + ParticlePropertyFlags props; + + props << PARTICLE_PROP_VISIBLE; + props << PARTICLE_PROP_ANIMATION_URL; + props << PARTICLE_PROP_ANIMATION_FPS; + props << PARTICLE_PROP_ANIMATION_FRAME_INDEX; + props << PARTICLE_PROP_ANIMATION_PLAYING; + props << PARTICLE_PROP_PAUSE_SIMULATION; + + QByteArray encoded = props.encode(); + qDebug() << "encoded="; + outputBufferBits((const unsigned char*)encoded.constData(), encoded.size()); + + ParticlePropertyFlags propsDecoded; + + propsDecoded.decode(encoded); + + qDebug() << "propsDecoded == props:" << (propsDecoded == props) << "{ expect true }"; + + QByteArray encodedAfterDecoded = propsDecoded.encode(); + + qDebug() << "encodedAfterDecoded="; + outputBufferBits((const unsigned char*)encoded.constData(), encoded.size()); + + } qDebug() << "******************************************************************************************"; }