// // Created by Bradley Austin Davis on 2015/07/08 // Copyright 2013-2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #pragma once #ifndef hifi_BufferParser_h #define hifi_BufferParser_h #include #include #include #include "GLMHelpers.h" #include "ByteCountCoding.h" #include "PropertyFlags.h" class BufferParser { public: BufferParser(const uint8_t* data, size_t size, size_t offset = 0) : _offset(offset), _data(data), _size(size) { } template inline void readValue(T& result) { Q_ASSERT(remaining() >= sizeof(T)); memcpy(&result, _data + _offset, sizeof(T)); _offset += sizeof(T); } inline void readUuid(QUuid& result) { readValue(result.data1); readValue(result.data2); readValue(result.data3); readValue(result.data4); result.data1 = qFromBigEndian(result.data1); result.data2 = qFromBigEndian(result.data2); result.data3 = qFromBigEndian(result.data3); } template inline void readFlags(PropertyFlags& result) { _offset += result.decode(_data + _offset, remaining()); } template inline void readCompressedCount(T& result) { // FIXME switch to a heapless implementation as soon as Brad provides it. ByteCountCoded codec; _offset += codec.decode(reinterpret_cast(_data + _offset), (int)remaining()); result = codec.data; } inline size_t remaining() const { return _size - _offset; } inline size_t offset() const { return _offset; } inline const uint8_t* data() const { return _data; } private: size_t _offset{ 0 }; const uint8_t* const _data; const size_t _size; }; template<> inline void BufferParser::readValue(quat& result) { size_t advance = unpackOrientationQuatFromBytes(_data + _offset, result); _offset += advance; } template<> inline void BufferParser::readValue(QString& result) { uint16_t length; readValue(length); result = QString((const char*)_data + _offset); } template<> inline void BufferParser::readValue(QUuid& result) { uint16_t length; readValue(length); Q_ASSERT(16 == length); readUuid(result); } template<> inline void BufferParser::readValue(xColor& result) { readValue(result.red); readValue(result.blue); readValue(result.green); } template<> inline void BufferParser::readValue(QVector& result) { uint16_t length; readValue(length); result.resize(length); memcpy(result.data(), _data + _offset, sizeof(glm::vec3) * length); _offset += sizeof(glm::vec3) * length; } template<> inline void BufferParser::readValue(QByteArray& result) { uint16_t length; readValue(length); result = QByteArray((char*)_data + _offset, (int)length); _offset += length; } #endif