#ifndef DICTIONARY_H #define DICTIONARY_H #include #include #include #ifdef ARDUINO #include #else typedef bool boolean; #endif //ARDUINO template 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 *split(char character); private: char *_string; }; } template 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