knx
ETS configurable knx-stack
data_property.cpp
Go to the documentation of this file.
1 #include "data_property.h"
2 #include "bits.h"
3 
4 #include <cstring>
5 
6 uint8_t DataProperty::read(uint16_t start, uint8_t count, uint8_t* data) const
7 {
8  if (start == 0)
9  {
10  pushWord(_currentElements, data);
11  return 1;
12  }
13 
14  if (count == 0 || _currentElements == 0 || start > _currentElements || count > _currentElements - start + 1)
15  return 0;
16 
17 
18  // we start counting with zero
19  start -= 1;
20 
21  // data is already big enough to hold the data
22  memcpy(data, _data + (start * ElementSize()), count * ElementSize());
23 
24  return count;
25 }
26 
27 uint8_t DataProperty::write(uint16_t start, uint8_t count, const uint8_t* data)
28 {
29  if (count == 0 || start > _maxElements || start + count > _maxElements + 1)
30  return 0;
31 
32  if (start == 0)
33  {
34  if (count == 1 && data[0] == 0 && data[1] == 0)
35  {
36  // reset _data
37  _currentElements = 0;
38 
39  if (_data)
40  {
41  delete[] _data;
42  _data = nullptr;
43  }
44 
45  return 1;
46  }
47  else
48  return 0;
49  }
50 
51  // we start counting with zero
52  start -= 1;
53 
54  if (start + count > _currentElements)
55  {
56  // reallocate memory for _data
57  uint8_t* oldData = _data;
58  size_t oldDataSize = _currentElements * ElementSize();
59 
60  size_t newDataSize = (start + count) * ElementSize();
61  _data = new uint8_t[newDataSize];
62  memset(_data, 0, newDataSize);
63 
64  if (oldData != nullptr)
65  {
66  memcpy(_data, oldData, oldDataSize);
67  delete[] oldData;
68  }
69 
70  _currentElements = start + count;
71  }
72 
73  memcpy(_data + (start * ElementSize()), data, count * ElementSize());
74 
75  return count;
76 }
77 
79  uint16_t maxElements, uint8_t access)
80  : Property(id, writeEnable, type, maxElements, access)
81 {}
82 
84 {
85  if (_data)
86  delete[] _data;
87 }
88 
90  uint16_t maxElements, uint8_t access, uint16_t value)
91  : Property(id, writeEnable, type, maxElements, access)
92 {
93  Property::write(value);
94 }
95 
97  uint16_t maxElements, uint8_t access, uint32_t value)
98  : Property(id, writeEnable, type, maxElements, access)
99 {
100  Property::write(value);
101 }
102 
104  uint16_t maxElements, uint8_t access, uint8_t value)
105  : Property(id, writeEnable, type, maxElements, access)
106 {
107  Property::write(value);
108 }
109 
111  uint16_t maxElements, uint8_t access, const uint8_t* value)
112  : Property(id, writeEnable, type, maxElements, access)
113 {
114  Property::write(value);
115 }
116 
118 {
119  return sizeof(_currentElements) + _maxElements * ElementSize();
120 }
121 
122 
123 const uint8_t* DataProperty::restore(const uint8_t* buffer)
124 {
125  uint16_t elements = 0;
126  buffer = popWord(elements, buffer);
127 
128  if (elements != _currentElements)
129  {
130  if (_data != nullptr)
131  delete[] _data;
132 
133  _data = new uint8_t[elements * ElementSize()];
134  _currentElements = elements;
135  }
136 
137  if (elements > 0)
138  buffer = popByteArray(_data, elements * ElementSize(), buffer);
139 
140  return buffer;
141 }
142 
143 
144 uint8_t* DataProperty::save(uint8_t* buffer)
145 {
146  buffer = pushWord(_currentElements, buffer);
147 
148  if (_currentElements > 0)
149  buffer = pushByteArray(_data, _currentElements * ElementSize(), buffer);
150 
151  return buffer;
152 }
153 
154 
155 const uint8_t* DataProperty::data()
156 {
157  return _data;
158 }
159 
160 const uint8_t* DataProperty::data(uint16_t elementIndex)
161 {
162  if ((elementIndex == 0) || (elementIndex > _currentElements))
163  return nullptr;
164 
165  elementIndex -= 1; // Starting from 0
166  uint16_t offset = elementIndex * ElementSize();
167  return _data + offset;
168 }
uint8_t * pushByteArray(const uint8_t *src, uint32_t size, uint8_t *data)
Definition: bits.cpp:82
const uint8_t * popByteArray(uint8_t *dst, uint32_t size, const uint8_t *data)
Definition: bits.cpp:48
uint8_t * pushWord(uint16_t w, uint8_t *data)
Definition: bits.cpp:64
const uint8_t * popWord(uint16_t &w, const uint8_t *data)
Definition: bits.cpp:34
~DataProperty() override
uint16_t saveSize() override
uint8_t * save(uint8_t *buffer) override
This method is called when the object should save its state to the buffer.
const uint8_t * data()
uint8_t write(uint16_t start, uint8_t count, const uint8_t *data) override
DataProperty(PropertyID id, bool writeEnable, PropertyDataType type, uint16_t maxElements, uint8_t access)
const uint8_t * restore(const uint8_t *buffer) override
This method is called when the object should restore its state from the buffer.
uint8_t read(uint16_t start, uint8_t count, uint8_t *data) const override
uint8_t ElementSize() const
Definition: property.cpp:31
uint16_t _maxElements
Definition: property.h:290
virtual uint8_t write(uint16_t start, uint8_t count, const uint8_t *data)=0
PropertyID
Definition: property.h:70
PropertyDataType
The data type of a property.
Definition: property.h:17