Arduino KVComm  master
Key-Value pair communication library for Arduino
KV_Builder.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #ifdef ARDUINO
4 
5 #include <KVComm/include/KVComm/KV_Iterator.hpp> // KV_Iterator
6 
7 #include <AH/STL/array> // std::array
8 #include <AH/STL/cstddef> // size_t
9 #include <AH/STL/initializer_list> // std::initializer_list
10 #include <AH/STL/vector> // std::vector
11 #include <string.h> // strlen
12 
13 #else
14 
15 #include <KVComm/KV_Iterator.hpp> // KV_Iterator
16 
17 #include <array> // std::array
18 #include <cstddef> // size_t
19 #include <cstring> // strlen
20 #include <initializer_list> // std::initializer_list
21 #include <iosfwd> // std::ostream forward declaration
22 #include <vector> // std::vector
23 #endif
24 
25 #if defined(ARDUINO) || defined(ARDUINO_TEST)
26 #include <Print.h>
27 #endif
28 
31 
107 class KV_Builder {
108  public:
109  KV_Builder(uint8_t *buffer, size_t bufferSize)
111 
141  template <class T>
142  bool add(const char *key, const T *data, size_t count) {
143  // don't allow empty keys
144  if (key == nullptr || key[0] == '\0')
145  return false;
146  // don't allow null data
147  if (data == nullptr && count != 0)
148  return false;
149  // Check if dictionary already contains a value with this key
150  KV_Iterator::iterator found = find(key);
151  if (found != KV_Iterator::end())
152  // if the dictionary already contains an element with the same key
153  return overwrite(found, data, count);
154  else
155  // this is a new key
156  return append(key, data, count);
157  }
158 
186  template <class T>
187  bool add(const char *key, const T &value) {
188  return add(key, &value, 1);
189  }
190 
216  bool add(const char *key, const char *data) {
217  return add(key, data, strlen(data) + 1);
218  }
219 
249  template <class T, size_t N>
250  bool add(const char *key, const T (&array)[N]) {
251  return add(key, array, N);
252  }
253 
281  template <class T>
282  bool add(const char *key, std::initializer_list<T> list) {
283  return add(key, list.begin(), list.size());
284  }
285 
315  template <class T, size_t N>
316  bool add(const char *key, const std::array<T, N> &array) {
317  return add(key, array.data(), N);
318  }
319 
347  template <class T>
348  bool add(const char *key, const std::vector<T> &vector) {
349  return add(key, vector.data(), vector.size());
350  }
351 
355  void clear() {
357  maxLen = bufferSize;
358  std::fill(buffer, buffer + bufferSize, 0);
359  }
360 
361 #if !defined(ARDUINO) || defined(DOXYGEN)
362  void print(std::ostream &os) const;
363  void printPython(std::ostream &os) const;
364 #endif // ARDUINO
365 
366 #if defined(ARDUINO) || defined(ARDUINO_TEST) || defined(DOXYGEN)
367 
374  void print(Print &os) const;
375 
383  void printPython(Print &os) const;
384 #endif
385 
386  private:
387  uint8_t *buffer;
388  size_t bufferSize;
391  size_t maxLen = bufferSize;
392 
395 
396  private:
401  uint8_t *writeHeader(const char *key, uint8_t typeID, size_t length);
402 
405  template <class T>
406  bool append(const char *key, const T *data, size_t count);
407 
412  template <class T>
413  bool overwrite(KV_Iterator::iterator existing, const T *data, size_t count);
414 
416  template <class T>
417  void overwrite(uint8_t *buffer, const T *data, size_t count);
418 
419  public:
421  const uint8_t *getBuffer() const { return buffer; }
423  size_t getBufferSize() const { return bufferSize; }
425  size_t getLength() const { return getBufferSize() - maxLen; }
426 
428  void changeBuffer(uint8_t *buffer, size_t size) {
429  this->buffer = buffer;
430  this->bufferwritelocation = buffer;
431  this->bufferSize = size;
432  this->maxLen = size;
433  }
434 
444  KV_Iterator::iterator find(const char *key) const;
445 };
446 
448 #define ADD_VAR(dict, var) dict.add(#var, var)
449 
451 template <size_t N>
453  public:
454  Static_KV_Builder() : KV_Builder(nullptr, 0) {
455  changeBuffer(buffer.data(), N);
456  }
457 
458  private:
459  std::array<uint8_t, N> buffer = {{}};
460 };
461 
463 
464 #include "KV_Builder.ipp"
KV_Builder.ipp
KV_Builder::add
bool add(const char *key, const char *data)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:216
KV_Builder
A class for serializing key-value/array data in a dictionary-like container that can be sent to anoth...
Definition: KV_Builder.hpp:107
KV_Builder::bufferSize
size_t bufferSize
Definition: KV_Builder.hpp:388
KV_Builder::add
bool add(const char *key, std::initializer_list< T > list)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:282
KV_Builder::changeBuffer
void changeBuffer(uint8_t *buffer, size_t size)
Replace the buffer.
Definition: KV_Builder.hpp:428
KV_Builder::add
bool add(const char *key, const T *data, size_t count)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:142
KV_Builder::add
bool add(const char *key, const T(&array)[N])
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:250
KV_Builder::getBuffer
const uint8_t * getBuffer() const
Get the buffer containing the dictionary.
Definition: KV_Builder.hpp:421
Static_KV_Builder::Static_KV_Builder
Static_KV_Builder()
Definition: KV_Builder.hpp:454
KV_Builder::KV_Builder
KV_Builder(uint8_t *buffer, size_t bufferSize)
Definition: KV_Builder.hpp:109
KV_Builder::append
bool append(const char *key, const T *data, size_t count)
Append the new element to the buffer.
Definition: KV_Builder.ipp:22
KV_Builder::writeHeader
uint8_t * writeHeader(const char *key, uint8_t typeID, size_t length)
Write the header of a new element into the buffer, advance the write pointer, and return a pointer to...
Definition: KV_Builder.cpp:29
KV_Builder::buffer
uint8_t * buffer
Definition: KV_Builder.hpp:387
KV_Iterator.hpp
Iterating over a dictionary generated by the KV_Builder, used for parsing and for checking if a key i...
KV_Builder::printPython
void printPython(std::ostream &os) const
Definition: KV_Builder.cpp:134
KV_Iterator::iterator
Definition: KV_Iterator.hpp:268
KV_Builder::add
bool add(const char *key, const std::vector< T > &vector)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:348
Static_KV_Builder
KV_Builder with a static buffer.
Definition: KV_Builder.hpp:452
KV_Builder::overwrite
bool overwrite(KV_Iterator::iterator existing, const T *data, size_t count)
Overwrite the existing element referenced by existing with the new data, if the type and size match.
Definition: KV_Builder.ipp:32
KV_Builder::bufferwritelocation
uint8_t * bufferwritelocation
A pointer to the first free/unused byte in the buffer.
Definition: KV_Builder.hpp:394
KV_Iterator::end
static iterator end()
End/sentinel iterator.
Definition: KV_Iterator.hpp:312
KV_Builder::clear
void clear()
Clear all elements of the dictionary.
Definition: KV_Builder.hpp:355
KV_Builder::find
KV_Iterator::iterator find(const char *key) const
Get the element with the given key.
Definition: KV_Builder.cpp:146
KV_Builder::getBufferSize
size_t getBufferSize() const
Get the total size of the buffer.
Definition: KV_Builder.hpp:423
KV_Builder::add
bool add(const char *key, const std::array< T, N > &array)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:316
KV_Builder::add
bool add(const char *key, const T &value)
Add a key-value pair to the dictionary, or update the existing value with the same key.
Definition: KV_Builder.hpp:187
KV_Builder::getLength
size_t getLength() const
Get the length of the used part of the buffer.
Definition: KV_Builder.hpp:425
KV_Builder::maxLen
size_t maxLen
The maximum remaining length that is still free.
Definition: KV_Builder.hpp:391
Static_KV_Builder::buffer
std::array< uint8_t, N > buffer
Definition: KV_Builder.hpp:459
KV_Builder::print
void print(std::ostream &os) const
Definition: KV_Builder.cpp:133