ESP8266_swiss_army_board/src/app/Dictionary.h
2019-05-01 23:31:10 +02:00

303 lines
7.6 KiB
C++

#ifndef DICTIONARY_H
#define DICTIONARY_H
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <Arduino.h>
template <typename T>
class Dictionary;
namespace DictionaryHelper
{
//String helper class with c style char array
class StringEntity
{
public:
StringEntity(const char *string) : _string(NULL)
{
if(string == NULL)
{
_string = (char *) malloc((sizeof(char)) * 2); //+1 for the string terminating character
strcpy(_string, "");
}
else
{
_string = (char *) malloc((strlen(string) * sizeof(char)) + 1); //+1 for the string terminating character
strcpy(_string, string);
}
}
StringEntity(const StringEntity &Object)
{
_string = (char *) malloc((strlen(Object._string) * sizeof(char)) + 1); //+1 for the string terminating character
strcpy(_string, Object._string);
}
~StringEntity(){free(_string);}
char *getString(){return _string;}
Dictionary<StringEntity> *split(char character);
private:
char *_string;
};
}
template <typename T>
class Dictionary
{
public:
Dictionary() :_parameter(NULL), _value(NULL), _next(NULL), _head(this){}
Dictionary(Dictionary const& dictionaryToCopy) //Copy constructor needed because of pointers
{
_head = this;
_next = NULL;
if(dictionaryToCopy._parameter != NULL)
{
_parameter = (char *) malloc((strlen(dictionaryToCopy._parameter) * sizeof(char)) + 1); //+1 for the string terminating character
_value = new T(*(dictionaryToCopy._value));
strcpy(_parameter, dictionaryToCopy._parameter);
}else
{
_parameter = NULL;
_value = NULL;
}
}
~Dictionary()
{
if(_head == this)
dispose();
free(_parameter);
//_parameter = NULL; Useless, just my c habits
delete _value;
//_value = NULL; //Useless, just my c habits
}
boolean add(const char *parameter, T *value)
{
Dictionary *dictionaryNode = new Dictionary(parameter, value);
return addNewNodeAtTheEnd(dictionaryNode);
}
boolean add(int indice, T *value)
{
char indiceToStr[10];
sprintf(indiceToStr,"%d", indice);
Dictionary *dictionaryNode = new Dictionary(indiceToStr, value);
return addNewNodeAtTheEnd(dictionaryNode);
}
boolean add(const char *parameter, T value)
{
Dictionary *dictionaryNode = new Dictionary(parameter, new T(value));
return addNewNodeAtTheEnd(dictionaryNode);
}
boolean add(int indice, T value)
{
char indiceToStr[10];
sprintf(indiceToStr,"%d", indice);
Dictionary *dictionaryNode = new Dictionary(indiceToStr, new T(value));
return addNewNodeAtTheEnd(dictionaryNode);
}
boolean remove(const char *parameter)
{
if(_head->_next == NULL) return false;
Dictionary *cursor = _head, *toDelete(NULL);
while(!isListEmpty(cursor->_next))
{
if(strcmp(cursor->_next->_parameter, parameter) == 0)
{
toDelete = cursor->_next;
cursor->_next = cursor->_next->_next;
delete toDelete;
return true;
}
cursor = cursor->_next;
}
return false;
}
boolean remove(int indice)
{
char indiceToStr[10];
sprintf(indiceToStr,"%d", indice);
return remove(indiceToStr);
}
boolean removeAt(unsigned int index)
{
unsigned int position(0);
if(_head->_next == NULL) return false;
Dictionary *cursor = _head, *toDelete(NULL);
while(!isListEmpty(cursor->_next))
{
if(position++ == index)
{
toDelete = cursor->_next;
cursor->_next = cursor->_next->_next;
delete toDelete;
return true;
}
cursor = cursor->_next;
}
return false;
}
T* get(const char *parameter)
{
if(parameter == NULL) return NULL;
if(isListEmpty(_head->_next))return NULL;
Dictionary *cursor = _head->_next;
while(!isListEmpty(cursor))
{
if(strcmp(cursor->_parameter,parameter) == 0)
return cursor->_value;
cursor = cursor->_next;
}
return NULL;
}
T* operator()(const char *parameter)
{
return get(parameter);
}
T* get(const unsigned int index)
{
unsigned int position(0);
if(isListEmpty(_head->_next))return NULL;
Dictionary *cursor = _head->_next;
while(!isListEmpty(cursor))
{
if(position++ == index)
return cursor->_value;
cursor = cursor->_next;
}
return NULL;
}
T* operator()(const unsigned int index)
{
return get(index);
}
unsigned int count()
{
unsigned int counter(0);
if(isListEmpty(_head->_next))return counter;
Dictionary *cursor = _head->_next;
while(!isListEmpty(cursor))
{
counter++;
cursor = cursor->_next;
}
return counter;
}
void clear() {this->dispose();}
void dispose()
{
if(isListEmpty(_head->_next))return;
Dictionary *cursor = _head->_next, *toDelete(NULL);
while(!isListEmpty(cursor))
{
toDelete = cursor;
cursor = cursor->_next;
delete toDelete;
}
_head = this;
_next = NULL;
}
const char *stringValue() const {return _value == NULL ? "" : _value->toString();}
const char *getParameter(const unsigned int index)
{
unsigned int position(0);
if(isListEmpty(_head->_next))return "";
Dictionary *cursor = _head->_next;
while(!isListEmpty(cursor))
{
if(position++ == index)
return cursor->_parameter;
cursor = cursor->_next;
}
return "";
}
protected:
Dictionary(const char *parameter, T *value) : Dictionary()
{
//We copy the parameter and the value
_parameter = (char *) malloc((strlen(parameter) * sizeof(char)) + 1); //+1 for the string terminating character
strcpy(_parameter, parameter);
_value = value;
}
boolean addNewNodeAtTheEnd(Dictionary *node)
{
if(node == NULL) return false;
node->_head = _head; //Every node should point to the first node
if(_next == NULL) //This is our first node then
{
_next = node;
return true;
}
// /!\ We have to work with the _next reference in the loop, if we don't it won't work as expected
Dictionary *cursor = _head;
while(!isListEmpty(cursor->_next))
{
if(strcmp(cursor->_next->_parameter, node->_parameter) == 0)//If we find the same parameter name, we replace it
{
delete (cursor->_next->_value);
cursor->_next->_value = new T(*(node->_value));
if(cursor->_next->_value == NULL)return false;
delete node;
return true;
}
cursor = cursor->_next;
}
cursor->_next = node;
return true;
}
boolean isListEmpty(Dictionary *node) {return node == NULL;}
char *_parameter;
T *_value;
Dictionary *_next;
Dictionary *_head;
private:
};
#endif //DICTIONARY_H