欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > strongswan链表结构

strongswan链表结构

2025/2/25 4:31:46 来源:https://blog.csdn.net/sinat_20184565/article/details/143469453  浏览:    关键词:strongswan链表结构

链表结构定义如下,public成员为公共的方法,count,first和last为私有成员,count表示链表中元素的数量,first和last分别指向链表的头和尾。public(linked_list_t结构)定义了一系列操作链表的方法,其必须为第一个结构成员,方便在公共方法和私有结构间转换。

struct private_linked_list_t {linked_list_t public;int count;element_t *first;element_t *last;
};

链表元素结构element_t如下,包括值value,和指向前一个(previous)和后一个元素(next)的两个指针:

struct element_t {void *value;element_t *previous;element_t *next;
};

如下函数创建通用的链表元素结构。

static element_t *element_create(void *value)
{element_t *this;INIT(this,.value = value,);return this;
}

创建新链表

创建新的链表,实例化链表结构,这里主要初始化了链表的公共方法,没有初始化私有成员。

linked_list_t *linked_list_create()
{private_linked_list_t *this;INIT(this,.public = {.get_count = _get_count,.create_enumerator = _create_enumerator,.reset_enumerator = (void*)_reset_enumerator,.get_first = _get_first,.get_last = _get_last,.find_first = _find_first,.insert_first = _insert_first,.insert_last = _insert_last,.insert_before = (void*)_insert_before,...},);return &this->public;

链表元素操作

向链表尾部插入元素时,对于链表为空的情况,链表成员first和last都指向此元素。对于链表非空的情况,链表中原有最后一个元素last的next指向新元素,新元素的previous指向原有最后一个元素。新元素保存为最后一个元素last。

METHOD(linked_list_t, insert_last, void, private_linked_list_t *this, void *item)
{element_t *element = element_create(item);if (this->count == 0) {    /* first entry in list */this->first = element;this->last = element;} else {element->previous = this->last;this->last->next = element;this->last = element;}this->count++;

链表起初只有一个元素(1st_elem),在尾部增加第二个元素之后如下图所示:

this->first                     this->first  |---<-------------<-------------------||                                |   |                                     |   
this->last                               |   |               this->last            |   |                                |   |                      |              |   |-----------|                     |-----------|            |-----------|        |   |           |--pre=NULL           |           |--pre=NULL  |           |--pre---|   |  1st_elem |                     |  1st_elem |            |  2nd_elem |            |           |--next=NULL          |           |--next----->|           |--next=NULL |-----------|                     |-----------|            |-----------|            

方法insert_first在链表首部插入一个元素,递增链表元素计数。

METHOD(linked_list_t, insert_first, void, private_linked_list_t *this, void *item)
{element_t *element = element_create(item);if (this->count == 0) {/* first entry in list */this->first = element;this->last = element;} else {element->next = this->first;this->first->previous = element;this->first = element;}this->count++;

链表起初只有一个元素(1st_elem),在首部增加第二个元素之后如下图所示:

this->first                     this->first   |---------<------<-----------------------------|                             |                               |     |                                              |
this->last                              |     |                     this->last               |   |                               |     |                             |                |   |-----------|                   |--------------|                 |---------------|        |     |           |--pre=NULL         |              |--pre=NULL       |               |--pre---|   |  1st_elem |                   | new_1st_elem |                 |  old_1st_elem |             |           |--next=NULL        |              |--next---------->|               |--next=NULL  |-----------|                   |--------------|                 |---------------|             

释放元素时,先行保存元素在链表中的下一个next和前一个元素previous。如果下一个元素有值,拿起previous应当指向上上个元素;否则,删除的为链表最后一个元素,previous变成最后一个元素。

如果前一个元素有值,其last应当指向下下个元素;否则,删除的为链表第一个元素,next变成第一个元素。

链表中的元素个数递减一,如果递减之后等于0,将链表的first和last指针置空。函数返回链表中被删除元素的下一个元素。

static element_t* remove_element(private_linked_list_t *this, element_t *element)
{element_t *next, *previous;next = element->next;previous = element->previous;free(element);if (next)next->previous = previous;elsethis->last = previous;if (previous)previous->next = next;elsethis->first = next;if (--this->count == 0){this->first = NULL;this->last = NULL;}return next;

链表枚举器

链表的枚举器结构定义如下,public成员为公共的方法,list和current为私有成员。public必须为第一个结构成员,方便在公共方法和私有结构间切换。

struct private_enumerator_t {enumerator_t public;private_linked_list_t *list;element_t *current;
};

枚举器结构的公共方法有以下三个。

struct enumerator_t {bool (*enumerate)(enumerator_t *this, ...);bool (*venumerate)(enumerator_t *this, va_list args);void (*destroy)(enumerator_t *this);
};

create_enumerator函数创建枚举器,初始化private_enumerator_t结构,链表结构实现了venumerate函数,enumerate函数使用枚举器默认的。私有成员list初始化为链表结构this,current成员指向链表首个元素。

METHOD(linked_list_t, create_enumerator, enumerator_t*, private_linked_list_t *this)
{   private_enumerator_t *enumerator;INIT(enumerator,.public = {.enumerate = enumerator_enumerate_default,.venumerate = _enumerate_current,.destroy = (void*)free,},.list = this,.current = this->first,);return &enumerator->public;

枚举器要求必须实现venumerate方法,其默认函数(enumerator_enumerate_default)是对venumerate的封装。此函数接受可变数量的参数,之后将这些参数传入venumerate方法。

bool enumerator_enumerate_default(enumerator_t *enumerator, ...)
{va_list args;bool result;if (!enumerator->venumerate) {DBG1(DBG_LIB, "!!! ENUMERATE DEFAULT: venumerate() missing !!!");return FALSE;}va_start(args, enumerator);result = enumerator->venumerate(enumerator, args);va_end(args);return result;

枚举器初始化的venumerate函数如下,在首次调用之后,其公共方法venumerate更换为_enumerate_next,用于获取枚举器的下一个元素。

METHOD(enumerator_t, enumerate_current, bool,private_enumerator_t *this, va_list args)
{this->public.venumerate = _enumerate_next;return do_enumerate(this, args);
}

初始化时,枚举器的current指向了链表结构的首个元素,如果current和传入参数都有效,将current元素的值赋予参数中。对于链表结构,可变参数的数量为1。

如果current为空,返回FALSE,表示整个枚举过程结束,链表结构的元素遍历完成。

static bool do_enumerate(private_enumerator_t *this, va_list args)
{   void **item;VA_ARGS_VGET(args, item);if (!this->current) return FALSE;if (item)*item = this->current->value;return TRUE;

通常在遍历第二个元素时,枚举器的venumerate函数换成了enumerate_next,枚举器的私有成员current指向链表下一个元素。do_enumerate执行以上的取值操作,取出下一个链表元素。

METHOD(enumerator_t, enumerate_next, bool, private_enumerator_t *this, va_list args)
{if (this->current)this->current = this->current->next;return do_enumerate(this, args);
}

枚举器使用完之后,需要由reset_enumerator复位,枚举器的current再次指向链表结构的首个元素,枚举器的公共方法venumerate恢复为指向enumerate_current函数。

METHOD(linked_list_t, reset_enumerator, void,private_linked_list_t *this, private_enumerator_t *enumerator)
{enumerator->current = this->first;enumerator->public.venumerate = _enumerate_current;
}

strongswan-5.9.14

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词