Overte C++ Documentation
BufferParser.h
1 //
2 // Created by Bradley Austin Davis on 2015/07/08
3 // Copyright 2013-2015 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 
9 #pragma once
10 #ifndef hifi_BufferParser_h
11 #define hifi_BufferParser_h
12 
13 #include <cstdint>
14 
15 #include <QUuid>
16 #include <QtEndian>
17 
18 #include "GLMHelpers.h"
19 #include "ByteCountCoding.h"
20 #include "PropertyFlags.h"
21 #include <glm/gtc/type_ptr.hpp>
22 
23 class BufferParser {
24 public:
25  BufferParser(const uint8_t* data, size_t size, size_t offset = 0) :
26  _offset(offset), _data(data), _size(size) {
27  }
28 
29  template<typename T>
30  inline void readValue(T& result) {
31  Q_ASSERT(remaining() >= sizeof(T));
32  memcpy(&result, _data + _offset, sizeof(T));
33  _offset += sizeof(T);
34  }
35 
36  inline void readUuid(QUuid& result) {
37  readValue(result.data1);
38  readValue(result.data2);
39  readValue(result.data3);
40  readValue(result.data4);
41  result.data1 = qFromBigEndian<quint32>(result.data1);
42  result.data2 = qFromBigEndian<quint16>(result.data2);
43  result.data3 = qFromBigEndian<quint16>(result.data3);
44  }
45 
46  template <typename T>
47  inline void readFlags(PropertyFlags<T>& result) {
48  _offset += result.decode(_data + _offset, remaining());
49  }
50 
51  template<typename T>
52  inline void readCompressedCount(T& result) {
53  // FIXME switch to a heapless implementation as soon as Brad provides it.
54  ByteCountCoded<T> codec;
55  _offset += codec.decode(reinterpret_cast<const char*>(_data + _offset), (int)remaining());
56  result = codec.data;
57  }
58 
59  inline size_t remaining() const {
60  return _size - _offset;
61  }
62 
63  inline size_t offset() const {
64  return _offset;
65  }
66 
67  inline const uint8_t* data() const {
68  return _data;
69  }
70 
71 private:
72 
73  size_t _offset{ 0 };
74  const uint8_t* const _data;
75  const size_t _size;
76 };
77 
78 
79 template<>
80 inline void BufferParser::readValue<quat>(quat& result) {
81  size_t advance = unpackOrientationQuatFromBytes(_data + _offset, result);
82  _offset += advance;
83 }
84 
85 template<>
86 inline void BufferParser::readValue(QString& result) {
87  uint16_t length; readValue(length);
88  result = QString((const char*)_data + _offset);
89 }
90 
91 template<>
92 inline void BufferParser::readValue(QUuid& result) {
93  uint16_t length; readValue(length);
94  Q_ASSERT(16 == length);
95  readUuid(result);
96 }
97 
98 template<>
99 inline void BufferParser::readValue(QVector<glm::vec3>& result) {
100  uint16_t length; readValue(length);
101  result.resize(length);
102  for (int i=0; i<length; i++) {
103  memcpy(glm::value_ptr(result[i]), _data + _offset + (sizeof(glm::vec3)*i), sizeof(glm::vec3) * length);
104  }
105 
106  _offset += sizeof(glm::vec3) * length;
107 }
108 
109 template<>
110 inline void BufferParser::readValue(QByteArray& result) {
111  uint16_t length; readValue(length);
112  result = QByteArray((char*)_data + _offset, (int)length);
113  _offset += length;
114 }
115 
116 #endif