336 lines
8.3 KiB
C++
336 lines
8.3 KiB
C++
#ifndef DICTIONARY_H
|
|
#define DICTIONARY_H
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#ifdef ARDUINO
|
|
#include <Arduino.h>
|
|
#else
|
|
typedef bool boolean;
|
|
#endif //ARDUINO
|
|
|
|
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)));
|
|
_string[0] = '\0';
|
|
}
|
|
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);}
|
|
const char *getString() const {return _string;}
|
|
void setString(const char *string = NULL)
|
|
{
|
|
free(_string);_string = NULL;
|
|
|
|
if(string == NULL)
|
|
{
|
|
_string = (char *) malloc((sizeof(char)));
|
|
_string[0] = '\0';
|
|
}
|
|
else
|
|
{
|
|
_string = (char *) malloc((strlen(string) * sizeof(char)) + 1); //+1 for the string terminating character
|
|
strcpy(_string, 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 position)
|
|
{
|
|
unsigned int pos(0);
|
|
if(_head->_next == NULL) return false;
|
|
|
|
Dictionary *cursor = _head, *toDelete(NULL);
|
|
|
|
while(!isListEmpty(cursor->_next))
|
|
{
|
|
if(pos++ == position)
|
|
{
|
|
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 id)
|
|
{
|
|
char indiceToStr[10];
|
|
sprintf(indiceToStr,"%d", id);
|
|
|
|
return get(indiceToStr);
|
|
}
|
|
|
|
T* operator()(const unsigned int id)
|
|
{
|
|
char indiceToStr[10];
|
|
sprintf(indiceToStr,"%d", id);
|
|
|
|
return get(indiceToStr);
|
|
}
|
|
|
|
T* getAt(const unsigned int position)
|
|
{
|
|
unsigned int pos(0);
|
|
if(isListEmpty(_head->_next))return NULL;
|
|
|
|
Dictionary *cursor = _head->_next;
|
|
|
|
while(!isListEmpty(cursor))
|
|
{
|
|
if(pos++ == position)
|
|
return cursor->_value;
|
|
cursor = cursor->_next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
unsigned int count() const
|
|
{
|
|
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 ? NULL : _value->toString();}
|
|
const char *getParameter(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->_parameter;
|
|
cursor = cursor->_next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
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) const {return node == NULL;}
|
|
|
|
char *_parameter;
|
|
T *_value;
|
|
Dictionary *_next;
|
|
Dictionary *_head;
|
|
private:
|
|
};
|
|
|
|
|
|
|
|
#endif //DICTIONARY_H
|