You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libiec61850/src/common/map.c

188 lines
3.8 KiB
C

/*
* map.c
*
* Copyright 2013-2025 Michael Zillgith
*
* This file is part of libIEC61850.
*
* libIEC61850 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libIEC61850 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libIEC61850. If not, see <http://www.gnu.org/licenses/>.
*
* See COPYING file for the complete license text.
*/
#include "libiec61850_platform_includes.h"
#include "map.h"
typedef struct sMapEntry
{
void* key;
void* value;
} MapEntry;
static int
comparePointerKeys(void* key1, void* key2)
{
if (key2 == key1)
return 0;
else
return -1;
}
Map
Map_create()
{
Map map = (Map) GLOBAL_CALLOC(1, sizeof(struct sMap));
if (map)
{
map->entries = LinkedList_create();
map->compareKeys = comparePointerKeys;
}
return map;
}
int
Map_size(Map map)
{
return LinkedList_size(map->entries);
}
void*
Map_addEntry(Map map, void* key, void* value)
{
MapEntry* entry = (MapEntry*) GLOBAL_MALLOC(sizeof(MapEntry));
if (entry)
{
entry->key = key;
entry->value = value;
LinkedList_add(map->entries, entry);
return entry->key;
}
else
{
return NULL;
}
}
void*
Map_removeEntry(Map map, void* key, bool deleteKey)
{
LinkedList element = map->entries;
LinkedList lastElement = element;
MapEntry* entry;
void* value = NULL;
while ((element = LinkedList_getNext(element)) != NULL)
{
entry = (MapEntry*) element->data;
if (map->compareKeys(key, entry->key) == 0)
{
lastElement->next = element->next;
value = entry->value;
if (deleteKey == true)
GLOBAL_FREEMEM(entry->key);
GLOBAL_FREEMEM(entry);
GLOBAL_FREEMEM(element);
break;
}
lastElement = element;
}
return value;
}
void*
Map_getEntry(Map map, void* key)
{
LinkedList element = map->entries;
while ((element = LinkedList_getNext(element)) != NULL)
{
MapEntry* entry = (MapEntry*) element->data;
if (map->compareKeys(key, entry->key) == 0) {
return entry->value;
}
}
return NULL;
}
void
Map_delete(Map map, bool deleteKey)
{
LinkedList element = map->entries;
while ((element = LinkedList_getNext(element)) != NULL)
{
MapEntry* entry = (MapEntry*) element->data;
if (deleteKey == true)
GLOBAL_FREEMEM(entry->key);
GLOBAL_FREEMEM(entry->value);
}
LinkedList_destroy(map->entries);
GLOBAL_FREEMEM(map);
}
void
Map_deleteStatic(Map map, bool deleteKey)
{
LinkedList element = map->entries;
if (deleteKey == true)
{
while ((element = LinkedList_getNext(element)) != NULL)
{
MapEntry* entry = (MapEntry*) element->data;
GLOBAL_FREEMEM(entry->key);
}
}
LinkedList_destroy(map->entries);
GLOBAL_FREEMEM(map);
}
void
Map_deleteDeep(Map map, bool deleteKey, void (*valueDeleteFunction)(void*))
{
if (map)
{
LinkedList element = map->entries;
while ((element = LinkedList_getNext(element)) != NULL)
{
MapEntry* entry = (MapEntry*) element->data;
if (deleteKey == true)
GLOBAL_FREEMEM(entry->key);
valueDeleteFunction(entry->value);
}
LinkedList_destroy(map->entries);
GLOBAL_FREEMEM(map);
}
}