1
0
mirror of https://github.com/falk-werner/webfuse synced 2024-10-27 20:34:10 +00:00

added dlist

This commit is contained in:
Falk Werner 2019-04-03 23:34:39 +02:00
parent 7069478408
commit f60b984729
4 changed files with 197 additions and 0 deletions

View File

@ -48,6 +48,7 @@ set(EXTRA_CFLAGS
# libwebfuse-core # libwebfuse-core
add_library(webfuse-core STATIC add_library(webfuse-core STATIC
lib/webfuse/core/dlist.c
lib/webfuse/core/message.c lib/webfuse/core/message.c
lib/webfuse/core/message_queue.c lib/webfuse/core/message_queue.c
lib/webfuse/core/status.c lib/webfuse/core/status.c
@ -273,6 +274,7 @@ add_executable(alltests
test/msleep.cc test/msleep.cc
test/mock_authenticator.cc test/mock_authenticator.cc
test/test_container_of.cc test/test_container_of.cc
test/test_dlist.cc
test/test_response_parser.cc test/test_response_parser.cc
test/test_server.cc test/test_server.cc
test/test_timepoint.cc test/test_timepoint.cc

87
lib/webfuse/core/dlist.c Normal file
View File

@ -0,0 +1,87 @@
#include "webfuse/core/dlist.h"
#include "webfuse/core/util.h"
#include <stddef.h>
void wf_dlist_init(
struct wf_dlist * list)
{
list->first = NULL;
}
static void wf_dlist_item_cleanup_default(
struct wf_dlist_item * WF_UNUSED_PARAM(item),
void * WF_UNUSED_PARAM(user_data))
{
// empty
}
void wf_dlist_cleanup(
struct wf_dlist * list,
wf_dlist_item_cleanup_fn * cleanup,
void * user_data)
{
wf_dlist_item_cleanup_fn * effective_cleanup = (NULL != cleanup) ? cleanup : &wf_dlist_item_cleanup_default;
struct wf_dlist_item * item = list->first;
while (NULL != item)
{
struct wf_dlist_item * next = item->next;
effective_cleanup(item, user_data);
item = next;
}
list->first = NULL;
}
void wf_dlist_prepend(
struct wf_dlist * list,
struct wf_dlist_item * item)
{
if (NULL != list->first)
{
list->first->prev = item;
}
item->prev = NULL;
item->next = list->first;
list->first = item;
}
void wf_dlist_remove(
struct wf_dlist * list,
struct wf_dlist_item * item)
{
if (NULL != item->prev)
{
item->prev->next = item->next;
}
if (NULL != item->next)
{
item->next->prev = item->prev;
}
if (list->first == item)
{
list->first = item->next;
}
}
struct wf_dlist_item * wf_dlist_find_first(
struct wf_dlist * list,
wf_dlist_item_predicate_fn * predicate,
void * user_data)
{
struct wf_dlist_item * item = list->first;
while (NULL != item)
{
if (predicate(item, user_data))
{
break;
}
item = item->next;
}
return item;
}

59
lib/webfuse/core/dlist.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef WF_DLIST_H
#define WF_DLIST_H
#ifndef __cplusplus
#include <stdbool.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
struct wf_dlist_item
{
struct wf_dlist_item * prev;
struct wf_dlist_item * next;
};
struct wf_dlist
{
struct wf_dlist_item * first;
};
typedef void wf_dlist_item_cleanup_fn(
struct wf_dlist_item * item,
void * user_data);
typedef bool wf_dlist_item_predicate_fn(
struct wf_dlist_item * item,
void * user_data);
extern void wf_dlist_init(
struct wf_dlist * list);
extern void wf_dlist_cleanup(
struct wf_dlist * list,
wf_dlist_item_cleanup_fn * cleanup,
void * user_data);
extern void wf_dlist_prepend(
struct wf_dlist * list,
struct wf_dlist_item * item);
extern void wf_dlist_remove(
struct wf_dlist * list,
struct wf_dlist_item * item);
extern struct wf_dlist_item * wf_dlist_find_first(
struct wf_dlist * list,
wf_dlist_item_predicate_fn * predicate,
void * user_data);
#ifdef __cplusplus
}
#endif
#endif

49
test/test_dlist.cc Normal file
View File

@ -0,0 +1,49 @@
#include <gtest/gtest.h>
#include "webfuse/core/dlist.h"
#include "webfuse/core/container_of.h"
namespace
{
struct Item
{
wf_dlist_item item;
char value;
};
}
TEST(DList, prepend)
{
struct wf_dlist list;
wf_dlist_init(&list);
ASSERT_EQ(nullptr, list.first);
Item a;
a.value = 'a';
wf_dlist_prepend(&list, &a.item);
ASSERT_EQ(&a.item, list.first);
ASSERT_EQ(nullptr, a.item.next);
ASSERT_EQ(nullptr, a.item.prev);
Item b;
b.value = 'b';
wf_dlist_prepend(&list, &b.item);
ASSERT_EQ(&b.item, list.first);
ASSERT_EQ(&a.item, b.item.next);
ASSERT_EQ(nullptr, b.item.prev);
ASSERT_EQ(nullptr, a.item.next);
ASSERT_EQ(&b.item, a.item.prev);
Item c;
c.value = 'c';
wf_dlist_prepend(&list, &c.item);
ASSERT_EQ(&c.item, list.first);
ASSERT_EQ(&b.item, c.item.next);
ASSERT_EQ(nullptr, c.item.prev);
ASSERT_EQ(&a.item, b.item.next);
ASSERT_EQ(&c.item, b.item.prev);
ASSERT_EQ(nullptr, a.item.next);
ASSERT_EQ(&b.item, a.item.prev);
wf_dlist_cleanup(&list, nullptr, nullptr);
ASSERT_EQ(nullptr, list.first);
}