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

© COPYRIGHT(c) 2021 LandPower

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