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.

298 lines
7.8 KiB
C

/*****************************************************************************
* file lib/management/array.c
* author YuLiang
* version 1.0.0
* date 22-Sep-2021
* brief This file provides all the array related operation functions.
******************************************************************************
* Attention
*
* <h2><center>&copy; COPYRIGHT(c) 2021 LandPower</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of LandPower nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* 标准C库头文件. */
/* 用户代码头文件. */
#include "array.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Internal functions --------------------------------------------------------*/
/* 确保设置的数组成员没有内存越界如果超出数组长度则重新realloc:
a --
len --
mem_type -- 使
return: void */
static void _array_len_ensure(array_t *a, uint32_t len, int32_t mem_type)
{
if (a->alloced > len)
{
return;
}
a->index = XREALLOC(mem_type, a->index, sizeof(void *) * (a->alloced * 2));
memset(&a->index[a->alloced], 0, sizeof(void *) * a->alloced);
a->alloced *= 2;
if (a->alloced <= len)
{
_array_len_ensure(a, len, mem_type);
}
}
/* 查找数组a的第一个空位置.
a --
return: */
uint32_t _array_empty_slot(array_t *a)
{
uint32_t i = 0;
for(i = 0; i < a->active; i++)
{
if (NULL == a->index[i])
{
return i;
}
}
return i;
}
/* Interface functions -------------------------------------------------------*/
/* 初始化数组:
size --
mem_type -- 使
return: */
array_t *array_init(uint32_t size, int32_t mem_type)
{
array_t *a = XMALLOC(mem_type, sizeof(array_t));
/* 如果大小为0,设置默认大小. */
if (0 == size)
{
size = ARRAY_MIN_SIZE;
}
a->alloced = size;
a->active = 0;
a->index = XMALLOC(mem_type, sizeof(void *) * size);
return a;
}
/* 设置数组相应索引位置的值:
a --
i --
val --
mem_type -- 使
return: void */
void array_set(array_t *a, uint32_t i, void *val, int32_t mem_type)
{
_array_len_ensure(a, i, mem_type);
a->index[i] = val;
if (a->active <= i)
{
a->active = i + 1;
}
}
/* 删除数组相应索引位置的值:
a --
i --
return: void */
void array_unset(array_t *a, uint32_t i)
{
if (i >= a->alloced)
{
return;
}
a->index[i] = NULL;
/* 不是最后一个元素直接返回. */
if (i + 1 != a->active)
{
return;
}
/* 如果是最后一个元素,则将当前可使用指针前移. */
while(--a->active)
{
if (a->index[a->active - 1] != NULL)
{
break;
}
}
}
/* 将数据放入数组的第一个空位置:
a --
val --
mem_type -- 使
return: */
uint32_t array_append(array_t *a, void *val, int32_t mem_type)
{
uint32_t i = 0;
i = _array_empty_slot(a);
_array_len_ensure(a, i, mem_type);
a->index[i] = val;
if (a->active <= i)
{
a->active = i + 1;
}
return i;
}
/* 复制数组a:
a --
mem_type -- 使
return: */
array_t *array_copy(array_t *a, int32_t mem_type)
{
unsigned int size = 0;
array_t *array = XMALLOC(mem_type, sizeof(array_t));
array->active = a->active;
array->alloced = a->alloced;
size = sizeof(void *) * (a->alloced);
array->index = XMALLOC(mem_type, size);
memcpy(array->index, a->index, size);
return array;
}
/* 将数组a和数组b合并成数组a:
a -- 1
b -- 2
mem_type -- 使
return: void */
void array_merge(array_t *a, array_t *b, int32_t mem_type)
{
uint32_t size = 0;
if (0 == b->alloced)
{
return;
}
size = sizeof(void *) * (a->alloced + b->alloced);
a->index = XREALLOC(mem_type, a->index, size);
memcpy(&a->index[a->active], b->index, sizeof(void *) * b->active);
a->active = a->active + b->active;
a->alloced = a->alloced + b->alloced;
}
/* 释放array_t:
a --
mem_type -- 使
return: void */
void array_free_wrapper(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a);
}
/* 释放array_t->index:
a --
mem_type -- 使
return: void */
void array_free_index(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a->index);
}
/* 释放array_t和array_t->index:
a --
mem_type -- 使
return: void */
void array_free(array_t *a, int32_t mem_type)
{
XFREE(mem_type, a->index);
XFREE(mem_type, a);
}
/* 查询数组a的数据i:
a --
i --
return: */
void *array_lookup(array_t *a, uint32_t i)
{
return (i >= a->active) ? NULL : a->index[i];
}
/* 获取数组a中有效数据的个数:
a --
return: void */
uint32_t array_count(array_t *a)
{
uint32_t i = 0;
uint32_t count = 0;
for (i = 0; i < a->active; i++)
{
if (a->index[i] != NULL)
{
count++;
}
}
return count;
}
/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****/