|
|
/*****************************************************************************
|
|
|
* 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>© 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 ****/
|