Arduino KVComm  master
Key-Value pair communication library for Arduino
Public Member Functions | Private Member Functions | Private Attributes | List of all members
KV_Builder Class Reference

A class for serializing key-value/array data in a dictionary-like container that can be sent to another Arduino or to a computer. More...

#include <KVComm/KV_Builder.hpp>

Inheritance diagram for KV_Builder:
Collaboration diagram for KV_Builder:

Public Member Functions

 KV_Builder (uint8_t *buffer, size_t bufferSize)
 
template<class T >
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. More...
 
template<class T >
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. More...
 
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. More...
 
template<class T , size_t N>
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. More...
 
template<class T >
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. More...
 
template<class T , size_t N>
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. More...
 
template<class T >
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. More...
 
void clear ()
 Clear all elements of the dictionary. More...
 
void print (std::ostream &os) const
 
void printPython (std::ostream &os) const
 
void print (Print &os) const
 Dump the dictionary buffer to the given output stream in a human-readable format (offset + hexadecimal + ASCII). More...
 
void printPython (Print &os) const
 Dump the dictionary buffer to the given output stream as a Python bytes object. More...
 
const uint8_t * getBuffer () const
 Get the buffer containing the dictionary. More...
 
size_t getBufferSize () const
 Get the total size of the buffer. More...
 
size_t getLength () const
 Get the length of the used part of the buffer. More...
 
void changeBuffer (uint8_t *buffer, size_t size)
 Replace the buffer. More...
 
KV_Iterator::iterator find (const char *key) const
 Get the element with the given key. More...
 

Private Member Functions

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 where the data should be written. More...
 
template<class T >
bool append (const char *key, const T *data, size_t count)
 Append the new element to the buffer. More...
 
template<class T >
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. More...
 
template<class T >
void overwrite (uint8_t *buffer, const T *data, size_t count)
 (Over)write the data of an element to the buffer. More...
 

Private Attributes

uint8_t * buffer
 
size_t bufferSize
 
size_t maxLen = bufferSize
 The maximum remaining length that is still free. More...
 
uint8_t * bufferwritelocation = buffer
 A pointer to the first free/unused byte in the buffer. More...
 

Detailed Description

A class for serializing key-value/array data in a dictionary-like container that can be sent to another Arduino or to a computer.

The KV_Builder class provides an easy to use KV_Builder::add method that can be used with single values/objects, strings, arrays of values/objects, and vectors of values/objects.

int values[] = {1, 2, 3};
dict.add("key", values);

User types can be added to the dictionary as well, by specializing the KV_Type template.

Data structure

The dictionary is just a long array of bytes. Each key-value pair in the dictionary starts with a 4-byte header that contains a unique identifier of the type of the data, the length of the key (in bytes) and the length of the data (in bytes).

     0         1         2         3
+---------+---------+---------+---------+
| key len |  type   |    data length    |
+---------+---------+---------+---------+
|                  key                  |
+---------+---------+---------+---------+
|                  ...                  |
+---------+---------+---------+---------+
|             key             |  NULL   |
+---------+---------+---------+---------+
|                 data                  |
+---------+---------+---------+---------+
|                  ...                  |
+---------+---------+---------+---------+

└─1 byte──┘ 
└────────────────1 word─────────────────┘

The header is always aligned to a word boundary. The key starts at the second word. There is at least one NULL byte after the key, and at most four. The data always starts at a word boundary, right after the null bytes after the key. The data can be a single object, or an array of objects, without any padding.

The type identifier is defined using the KV_Type structs. These structs also define how objects of that type should be copied into or from the buffer, as well as the size of a single object.

There are two main types of data: fundamental types (int, float, bool, etc.) that can be memcpyd into or from the buffer, and user-defined types that have special functions for copying their data.
The former are defined in KV_Types.hpp, and an example of the latter can be found in LoggerMathTypes.hpp.

Todo:
LoggerMathTypes.hpp

Structured data cannot be memcpyd, because the compiler doesn't necessarily pack all of the data together, it's free to allow padding bytes where necessary. (Wikipedia: Data structure alignment)

String data is copied into the dictionary as an array of characters. The null terminator is included.

Definition at line 107 of file KV_Builder.hpp.

Constructor & Destructor Documentation

◆ KV_Builder()

KV_Builder ( uint8_t *  buffer,
size_t  bufferSize 
)
inline

Definition at line 109 of file KV_Builder.hpp.

Member Function Documentation

◆ add() [1/7]

bool add ( const char *  key,
const T *  data,
size_t  count 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the value to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
dataA pointer to the (array of) value(s) to add.
countThe number of elements in the array. The maximum size is 65535 bytes, so the maximum count is 65535 divided by the size of one element.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 142 of file KV_Builder.hpp.

◆ add() [2/7]

bool add ( const char *  key,
const T &  value 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is a single value.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the value to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
valueThe value to add. The maximum size is 65535 bytes.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 187 of file KV_Builder.hpp.

◆ add() [3/7]

bool add ( const char *  key,
const char *  data 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is a null-terminated string.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Parameters
keyThe key for this element. The maximum length is 255 characters.
dataThe string to add. The maximum length is 65534 characters.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 216 of file KV_Builder.hpp.

◆ add() [4/7]

bool add ( const char *  key,
const T(&)  array[N] 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is an array of values.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the values to add.
NThe number of values to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
arrayThe array of values to add. The maximum size is 65535 bytes.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 250 of file KV_Builder.hpp.

◆ add() [5/7]

bool add ( const char *  key,
std::initializer_list< T >  list 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is a list of values.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the values to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
listThe list of values to add. The maximum size is 65535 bytes.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 282 of file KV_Builder.hpp.

◆ add() [6/7]

bool add ( const char *  key,
const std::array< T, N > &  array 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is an std::array of values.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the values to add.
NThe number of values to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
arrayThe array of values to add. The maximum size is 65535 bytes.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 316 of file KV_Builder.hpp.

◆ add() [7/7]

bool add ( const char *  key,
const std::vector< T > &  vector 
)
inline

Add a key-value pair to the dictionary, or update the existing value with the same key.

The data of the element is an std::vector of values.

If the key can't be found in the dictionary, the new element is appended. If a value with the same key is found, and if the type and size are the same, the existing value is updated with the new value. If the type or size don't match, the dictionary is not altered.

Template Parameters
TThe type of the values to add.
Parameters
keyThe key for this element. The maximum length is 255 characters.
vectorThe vector of values to add. The maximum size is 65535 bytes.
Return values
trueThe element was added to the dictionary successfully, or the existing element with the same key was updated with the new value.
falseThe buffer is full, the key or data length is too large, or the type and size don't match the ones of the existing element with the same key.

Definition at line 348 of file KV_Builder.hpp.

◆ clear()

void clear ( )
inline

Clear all elements of the dictionary.

Definition at line 355 of file KV_Builder.hpp.

◆ print() [1/2]

void print ( std::ostream &  os) const

Definition at line 133 of file KV_Builder.cpp.

◆ printPython() [1/2]

void printPython ( std::ostream &  os) const

Definition at line 134 of file KV_Builder.cpp.

◆ print() [2/2]

void print ( Print &  os) const

Dump the dictionary buffer to the given output stream in a human-readable format (offset + hexadecimal + ASCII).

Parameters
osThe stream to print to.

Definition at line 140 of file KV_Builder.cpp.

◆ printPython() [2/2]

void printPython ( Print &  os) const

Dump the dictionary buffer to the given output stream as a Python bytes object.

Parameters
osThe stream to print to.

Definition at line 141 of file KV_Builder.cpp.

◆ writeHeader()

uint8_t * writeHeader ( const char *  key,
uint8_t  typeID,
size_t  length 
)
private

Write the header of a new element into the buffer, advance the write pointer, and return a pointer to where the data should be written.

Returns a null pointer if the element is too large for the buffer, and in that case, the write pointer is unaltered.

Definition at line 29 of file KV_Builder.cpp.

◆ append()

bool append ( const char *  key,
const T *  data,
size_t  count 
)
private

Append the new element to the buffer.

Returns false if the element is too large for the buffer.

Definition at line 22 of file KV_Builder.ipp.

◆ overwrite() [1/2]

bool overwrite ( KV_Iterator::iterator  existing,
const T *  data,
size_t  count 
)
private

Overwrite the existing element referenced by existing with the new data, if the type and size match.

Returns false if the type or size doesn't match, and in that case, nothing is overwritten.

Definition at line 32 of file KV_Builder.ipp.

◆ overwrite() [2/2]

void overwrite ( uint8_t *  buffer,
const T *  data,
size_t  count 
)
private

(Over)write the data of an element to the buffer.

Definition at line 14 of file KV_Builder.ipp.

◆ getBuffer()

const uint8_t* getBuffer ( ) const
inline

Get the buffer containing the dictionary.

Definition at line 421 of file KV_Builder.hpp.

◆ getBufferSize()

size_t getBufferSize ( ) const
inline

Get the total size of the buffer.

Definition at line 423 of file KV_Builder.hpp.

◆ getLength()

size_t getLength ( ) const
inline

Get the length of the used part of the buffer.

Definition at line 425 of file KV_Builder.hpp.

◆ changeBuffer()

void changeBuffer ( uint8_t *  buffer,
size_t  size 
)
inline

Replace the buffer.

Definition at line 428 of file KV_Builder.hpp.

◆ find()

KV_Iterator::iterator find ( const char *  key) const

Get the element with the given key.

Parameters
keyThe unique key of the element to retreive.
Returns
An iterator to the element with the given key, or a default-constructed KV_Iterator::iterator if the key was not found in the dictionary.

Definition at line 146 of file KV_Builder.cpp.

Member Data Documentation

◆ buffer

uint8_t* buffer
private

Definition at line 387 of file KV_Builder.hpp.

◆ bufferSize

size_t bufferSize
private

Definition at line 388 of file KV_Builder.hpp.

◆ maxLen

size_t maxLen = bufferSize
private

The maximum remaining length that is still free.

Starts off as the buffer size, reaches zero when the buffer is full.

Definition at line 391 of file KV_Builder.hpp.

◆ bufferwritelocation

uint8_t* bufferwritelocation = buffer
private

A pointer to the first free/unused byte in the buffer.

Definition at line 394 of file KV_Builder.hpp.


The documentation for this class was generated from the following files:
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
Static_KV_Builder
KV_Builder with a static buffer.
Definition: KV_Builder.hpp:452