|
|
| version 1.1.2.1, 2011/05/03 08:39:14 | version 1.3.2.3, 2011/08/26 13:19:35 |
|---|---|
| Line 1 | Line 1 |
| /************************************************************************* | |
| * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org> | |
| * by Michael Pounov <misho@elwix.org> | |
| * | |
| * $Author$ | |
| * $Id$ | |
| * | |
| ************************************************************************** | |
| The ELWIX and AITNET software is distributed under the following | |
| terms: | |
| All of the documentation and software included in the ELWIX and AITNET | |
| Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> | |
| Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 | |
| by Michael Pounov <misho@elwix.org>. All rights reserved. | |
| 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. All advertising materials mentioning features or use of this software | |
| must display the following acknowledgement: | |
| This product includes software developed by Michael Pounov <misho@elwix.org> | |
| ELWIX - Embedded LightWeight unIX and its contributors. | |
| 4. Neither the name of AITNET 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 AITNET 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 REGENTS 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. | |
| */ | |
| #include "global.h" | #include "global.h" |
| Line 23 io_sarrInit(int numItems, int segLen) | Line 68 io_sarrInit(int numItems, int segLen) |
| arr->sarr_num = numItems; | arr->sarr_num = numItems; |
| arr->sarr_seg = segLen; | arr->sarr_seg = segLen; |
| arr->sarr_siz = numItems / segLen; | arr->sarr_siz = numItems / segLen + 1; |
| arr->sarr_data = calloc(arr->sarr_siz, sizeof(sarr_seg_t)); | arr->sarr_data = calloc(arr->sarr_siz, sizeof(sarr_seg_t)); |
| if (!arr->sarr_data) { | if (!arr->sarr_data) { |
| LOGERR; | LOGERR; |
| Line 45 io_sarrDestroy(sarr_t ** __restrict parr) | Line 90 io_sarrDestroy(sarr_t ** __restrict parr) |
| { | { |
| register int i; | register int i; |
| assert(parr); | assert(parr && *parr); |
| if (!parr) | if (!parr || !*parr) |
| return; | return; |
| for (i = 0; i < (*parr)->sarr_siz; i++) | for (i = 0; i < (*parr)->sarr_siz; i++) |
| Line 92 io_sarrVacuum(sarr_t * __restrict arr) | Line 137 io_sarrVacuum(sarr_t * __restrict arr) |
| return cx; | return cx; |
| } | } |
| /* | |
| * io_sarrGrow() - Grow/Shrink dynamic split-order array, Use with care when it shrink!!! | |
| * @arr = Array | |
| * @newNumItems = Number of Items | |
| * return: -1 error, 0 ok | |
| */ | |
| int | |
| io_sarrGrow(sarr_t * __restrict arr, int newNumItems) | |
| { | |
| sarr_seg_t *data; | |
| int seg, n = 0; | |
| register int i; | |
| assert(arr); | |
| if (!arr) | |
| return -1; | |
| arr->sarr_num = newNumItems; | |
| seg = newNumItems / arr->sarr_seg + 1; | |
| if (arr->sarr_siz == seg) | |
| return n; | |
| if (arr->sarr_siz < seg) | |
| n = seg - arr->sarr_siz; | |
| else | |
| for (i = seg; i < arr->sarr_siz; i++) | |
| if (arr->sarr_data[i]) | |
| free(arr->sarr_data[i]); | |
| arr->sarr_siz = seg; | |
| data = realloc(arr->sarr_data, arr->sarr_siz * sizeof(sarr_seg_t)); | |
| if (!data) { | |
| LOGERR; | |
| return -1; | |
| } else | |
| arr->sarr_data = data; | |
| memset(arr->sarr_data + (arr->sarr_siz - n), 0, n * sizeof(sarr_seg_t)); | |
| return 0; | |
| } | |
| /* | |
| * io_sarrGet() - Get element from dynamic split-order array | |
| * @arr = Array | |
| * @idx = Index (warning 1st element is at position 1) | |
| * return: NULL not found, !=NULL element | |
| */ | |
| inline void * | |
| io_sarrGet(sarr_t * __restrict arr, u_int idx) | |
| { | |
| void *ret = NULL; | |
| sarr_seg_t seg; | |
| assert(arr); | |
| if (!arr || idx < 1 || arr->sarr_num < idx) | |
| return ret; | |
| seg = arr->sarr_data[idx / arr->sarr_seg]; | |
| if (seg) | |
| ret = seg[idx % arr->sarr_seg]; | |
| return ret; | |
| } | |
| /* | |
| * io_sarrGet2() - Always get element from dynamic split-order array | |
| * Function automatic grow array. Good use for Hash tables! | |
| * @arr = Array | |
| * @idx = Index (warning 1st element is at position 1) | |
| * return: NULL not found, !=NULL element | |
| */ | |
| void * | |
| io_sarrGet2(sarr_t * __restrict arr, u_int idx) | |
| { | |
| assert(arr); | |
| if (!arr || idx < 1) | |
| return NULL; | |
| if (arr->sarr_num < idx) | |
| if (io_sarrGrow(arr, idx)) | |
| return NULL; | |
| return io_sarrGet(arr, idx); | |
| } | |
| /* | |
| * io_sarrSet() - Set element to dynamic split-order array | |
| * @arr = Array | |
| * @idx = Index (warning 1st element is at position 1) | |
| * @data = Value | |
| * return: NULL error or empty, !=NULL old value in element | |
| */ | |
| inline void * | |
| io_sarrSet(sarr_t * __restrict arr, u_int idx, void *data) | |
| { | |
| void *ret = NULL; | |
| sarr_seg_t seg; | |
| register int pos; | |
| assert(arr); | |
| if (!arr || idx < 1 || arr->sarr_num < idx) | |
| return ret; | |
| seg = arr->sarr_data[idx / arr->sarr_seg]; | |
| if (!seg) { | |
| seg = calloc(arr->sarr_seg, sizeof(void*)); | |
| if (!seg) { | |
| LOGERR; | |
| return ret; | |
| } else | |
| memset(seg, 0, arr->sarr_seg * sizeof(void*)); | |
| arr->sarr_data[idx / arr->sarr_seg] = seg; | |
| } | |
| pos = idx % arr->sarr_seg; | |
| ret = seg[pos]; | |
| seg[pos] = data; | |
| return ret; | |
| } | |
| /* | |
| * io_sarr2array() - Convert from split-order array to dynamic array | |
| * @sa = split array | |
| * @sarrFree = after convert split array !=0 will be destroyed sarray | |
| * return: NULL error or != NULL new array | |
| */ | |
| array_t * | |
| io_sarr2array(sarr_t ** __restrict sa, int sarrFree) | |
| { | |
| array_t *arr = NULL; | |
| int el; | |
| register int i; | |
| assert(sa && *sa); | |
| if (!sa || !*sa) | |
| return NULL; | |
| el = io_sarrSize(*sa); | |
| arr = io_arrayInit(el); | |
| if (!arr) | |
| return NULL; | |
| for (i = 0; i < el; i++) | |
| io_arraySet(arr, i, io_sarrGet(*sa, i + 1)); | |
| if (sarrFree) { | |
| free(*sa); | |
| *sa = NULL; | |
| } | |
| return arr; | |
| } | |
| /* | |
| * io_array2sarr() - Convert from dynamic array to split-order array | |
| * @a = array | |
| * @segLen = Length of segment | |
| * @arrFree = after convert array !=0 will be destroyed | |
| * return: NULL error or != NULL new sarr | |
| */ | |
| sarr_t * | |
| io_array2sarr(array_t ** __restrict a, int segLen, int arrFree) | |
| { | |
| sarr_t *sa = NULL; | |
| int el; | |
| register int i; | |
| assert(a && *a); | |
| if (!a || !*a) | |
| return NULL; | |
| el = io_arraySize(*a); | |
| sa = io_sarrInit(el, segLen); | |
| if (!sa) | |
| return NULL; | |
| for (i = 0; i < el; i++) | |
| io_sarrSet(sa, i + 1, io_arrayGet(*a, i)); | |
| if (arrFree) { | |
| free(*a); | |
| *a = NULL; | |
| } | |
| return sa; | |
| } |