LCOV - code coverage report
Current view: top level - utils - list.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 111 111 100.0 %
Date: 2021-04-29 23:48:07 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2020
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / common tools sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/list.h>
      27             : 
      28             : /* GF_List modes, ONLY ONE CAN BE DEFINED
      29             : 
      30             :         linked-list
      31             :         #define GF_LIST_LINKED
      32             : 
      33             :         double navigation linked-list
      34             :         #define GF_LIST_DOUBLE_LINKED
      35             : 
      36             :         single step memory array
      37             :         #define GF_LIST_ARRAY
      38             : 
      39             :         multi-step memory array without gf_realloc on remove, using the GF_LIST_REALLOC macro
      40             :         GF_LIST_ARRAY_GROW
      41             : */
      42             : 
      43             : /*after some tuning, this seems to be the fastest mode on WINCE*/
      44             : #ifdef _WIN32_WCE
      45             : #define GF_LIST_LINKED
      46             : #else
      47             : #define GF_LIST_ARRAY_GROW
      48             : #endif
      49             : 
      50             : #define GF_LIST_REALLOC(a) (a = a ? (3*a/2) : 10)
      51             : //#define GF_LIST_REALLOC(a) (a++)
      52             : 
      53             : 
      54             : #if defined(GF_LIST_LINKED)
      55             : 
      56             : typedef struct tagIS
      57             : {
      58             :         struct tagIS *next;
      59             :         void *data;
      60             : } ItemSlot;
      61             : 
      62             : struct _tag_array
      63             : {
      64             :         struct tagIS *head;
      65             :         struct tagIS *tail;
      66             :         u32 entryCount;
      67             :         s32 foundEntryNumber;
      68             :         struct tagIS *foundEntry;
      69             : };
      70             : 
      71             : 
      72             : GF_EXPORT
      73             : GF_List * gf_list_new()
      74             : {
      75             :         GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
      76             :         if (! nlist) return NULL;
      77             :         nlist->head = nlist->foundEntry = NULL;
      78             :         nlist->tail = NULL;
      79             :         nlist->foundEntryNumber = -1;
      80             :         nlist->entryCount = 0;
      81             :         return nlist;
      82             : }
      83             : 
      84             : GF_EXPORT
      85             : void gf_list_del(GF_List *ptr)
      86             : {
      87             :         if (!ptr) return;
      88             :         while (ptr->entryCount) gf_list_rem(ptr, 0);
      89             :         gf_free(ptr);
      90             : }
      91             : 
      92             : GF_EXPORT
      93             : void gf_list_reset(GF_List *ptr)
      94             : {
      95             :         while (ptr && ptr->entryCount) gf_list_rem(ptr, 0);
      96             : }
      97             : 
      98             : GF_EXPORT
      99             : GF_Err gf_list_add(GF_List *ptr, void* item)
     100             : {
     101             :         ItemSlot *entry;
     102             :         if (! ptr) return GF_BAD_PARAM;
     103             :         entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
     104             :         if (!entry) return GF_OUT_OF_MEM;
     105             :         entry->data = item;
     106             :         entry->next = NULL;
     107             :         if (! ptr->head) {
     108             :                 ptr->head = entry;
     109             :                 ptr->entryCount = 1;
     110             :         } else {
     111             :                 ptr->entryCount += 1;
     112             :                 ptr->tail->next = entry;
     113             :         }
     114             :         ptr->tail = entry;
     115             :         ptr->foundEntryNumber = ptr->entryCount - 1;
     116             :         ptr->foundEntry = entry;
     117             :         return GF_OK;
     118             : }
     119             : 
     120             : GF_EXPORT
     121             : u32 gf_list_count(const GF_List *ptr)
     122             : {
     123             :         if (!ptr) return 0;
     124             :         return ptr->entryCount;
     125             : }
     126             : 
     127             : GF_EXPORT
     128             : void *gf_list_get(GF_List *ptr, u32 itemNumber)
     129             : {
     130             :         ItemSlot *entry;
     131             :         u32 i;
     132             : 
     133             :         if (!ptr || (itemNumber >= ptr->entryCount) ) return NULL;
     134             : 
     135             :         if (!ptr->foundEntry || (itemNumber < (u32) ptr->foundEntryNumber) ) {
     136             :                 ptr->foundEntryNumber = 0;
     137             :                 ptr->foundEntry = ptr->head;
     138             :         }
     139             :         entry = ptr->foundEntry;
     140             :         for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
     141             :                 entry = entry->next;
     142             :         }
     143             :         ptr->foundEntryNumber = itemNumber;
     144             :         ptr->foundEntry = entry;
     145             :         return (void *) entry->data;
     146             : }
     147             : 
     148             : GF_EXPORT
     149             : void *gf_list_last(GF_List *ptr)
     150             : {
     151             :         ItemSlot *entry;
     152             :         if (!ptr || !ptr->entryCount) return NULL;
     153             :         entry = ptr->head;
     154             :         while (entry->next) entry = entry->next;
     155             :         return entry->data;
     156             : }
     157             : 
     158             : GF_EXPORT
     159             : GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
     160             : {
     161             :         ItemSlot *tmp, *tmp2;
     162             :         u32 i;
     163             : 
     164             :         /* !! if head is null (empty list)*/
     165             :         if ( (! ptr) || (! ptr->head) || (ptr->head && !ptr->entryCount) || (itemNumber >= ptr->entryCount) )
     166             :                 return GF_BAD_PARAM;
     167             : 
     168             :         /*we delete the head*/
     169             :         if (! itemNumber) {
     170             :                 tmp = ptr->head;
     171             :                 ptr->head = ptr->head->next;
     172             :                 ptr->entryCount --;
     173             :                 ptr->foundEntry = ptr->head;
     174             :                 ptr->foundEntryNumber = 0;
     175             :                 gf_free(tmp);
     176             :                 /*that was the last entry, reset the tail*/
     177             :                 if (!ptr->entryCount) {
     178             :                         ptr->tail = ptr->head = ptr->foundEntry = NULL;
     179             :                         ptr->foundEntryNumber = -1;
     180             :                 }
     181             :                 return GF_OK;
     182             :         }
     183             : 
     184             :         tmp = ptr->head;
     185             :         i = 0;
     186             :         while (i < itemNumber - 1) {
     187             :                 tmp = tmp->next;
     188             :                 i++;
     189             :         }
     190             :         tmp2 = tmp->next;
     191             :         tmp->next = tmp2->next;
     192             :         /*if we deleted the last entry, update the tail !!!*/
     193             :         if (! tmp->next || (ptr->tail == tmp2) ) {
     194             :                 ptr->tail = tmp;
     195             :                 tmp->next = NULL;
     196             :         }
     197             : 
     198             :         gf_free(tmp2);
     199             :         ptr->entryCount --;
     200             :         ptr->foundEntry = ptr->head;
     201             :         ptr->foundEntryNumber = 0;
     202             : 
     203             :         return GF_OK;
     204             : }
     205             : 
     206             : GF_EXPORT
     207             : GF_Err gf_list_rem_last(GF_List *ptr)
     208             : {
     209             :         return gf_list_rem(ptr, ptr->entryCount-1);
     210             : }
     211             : 
     212             : GF_EXPORT
     213             : GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
     214             : {
     215             :         u32 i;
     216             :         ItemSlot *tmp, *tmp2;
     217             : 
     218             :         if (!ptr || !item) return GF_BAD_PARAM;
     219             :         /*if last entry or first of an empty array...*/
     220             :         if (position >= ptr->entryCount) return gf_list_add(ptr, item);
     221             : 
     222             :         tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
     223             :         tmp2->data = item;
     224             :         tmp2->next = NULL;
     225             :         /*special case for the head*/
     226             :         if (position == 0) {
     227             :                 tmp2->next = ptr->head;
     228             :                 ptr->head = tmp2;
     229             :                 ptr->entryCount ++;
     230             :                 ptr->foundEntry = tmp2;
     231             :                 ptr->foundEntryNumber = 0;
     232             :                 return GF_OK;
     233             :         }
     234             :         tmp = ptr->head;
     235             :         for (i = 1; i < position; i++) {
     236             :                 tmp = tmp->next;
     237             :                 if (!tmp)
     238             :                         break;
     239             :         }
     240             :         tmp2->next = tmp->next;
     241             :         tmp->next = tmp2;
     242             :         ptr->entryCount ++;
     243             :         ptr->foundEntry = tmp2;
     244             :         ptr->foundEntryNumber = i;
     245             :         return GF_OK;
     246             : }
     247             : 
     248             : #elif defined(GF_LIST_DOUBLE_LINKED)
     249             : 
     250             : 
     251             : typedef struct tagIS
     252             : {
     253             :         struct tagIS *next;
     254             :         struct tagIS *prev;
     255             :         void *data;
     256             : } ItemSlot;
     257             : 
     258             : struct _tag_array
     259             : {
     260             :         struct tagIS *head;
     261             :         struct tagIS *tail;
     262             :         u32 entryCount;
     263             :         s32 foundEntryNumber;
     264             :         struct tagIS *foundEntry;
     265             : };
     266             : 
     267             : 
     268             : GF_EXPORT
     269             : GF_List * gf_list_new()
     270             : {
     271             :         GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
     272             :         if (! nlist) return NULL;
     273             :         nlist->head = nlist->foundEntry = NULL;
     274             :         nlist->tail = NULL;
     275             :         nlist->foundEntryNumber = -1;
     276             :         nlist->entryCount = 0;
     277             :         return nlist;
     278             : }
     279             : 
     280             : GF_EXPORT
     281             : void gf_list_del(GF_List *ptr)
     282             : {
     283             :         if (!ptr) return;
     284             :         while (ptr->entryCount) {
     285             :                 gf_list_rem(ptr, 0);
     286             :         }
     287             :         gf_free(ptr);
     288             : }
     289             : 
     290             : GF_EXPORT
     291             : void gf_list_reset(GF_List *ptr)
     292             : {
     293             :         while (ptr && ptr->entryCount) gf_list_rem(ptr, 0);
     294             : }
     295             : 
     296             : GF_EXPORT
     297             : GF_Err gf_list_add(GF_List *ptr, void* item)
     298             : {
     299             :         ItemSlot *entry;
     300             :         if (! ptr) return GF_BAD_PARAM;
     301             :         entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
     302             :         if (!entry) return GF_OUT_OF_MEM;
     303             :         entry->data = item;
     304             :         entry->next = entry->prev = NULL;
     305             : 
     306             :         if (! ptr->head) {
     307             :                 ptr->head = entry;
     308             :                 ptr->entryCount = 1;
     309             :         } else {
     310             :                 ptr->entryCount += 1;
     311             :                 entry->prev = ptr->tail;
     312             :                 ptr->tail->next = entry;
     313             :         }
     314             :         ptr->tail = entry;
     315             :         ptr->foundEntryNumber = ptr->entryCount - 1;
     316             :         ptr->foundEntry = entry;
     317             :         return GF_OK;
     318             : }
     319             : 
     320             : 
     321             : GF_EXPORT
     322             : u32 gf_list_count(GF_List *ptr)
     323             : {
     324             :         if (! ptr) return 0;
     325             :         return ptr->entryCount;
     326             : }
     327             : 
     328             : GF_EXPORT
     329             : void *gf_list_get(GF_List *ptr, u32 itemNumber)
     330             : {
     331             :         ItemSlot *entry;
     332             :         u32 i;
     333             : 
     334             :         if (!ptr || !ptr->head || (itemNumber >= ptr->entryCount) ) return NULL;
     335             : 
     336             :         if (!itemNumber) {
     337             :                 ptr->foundEntry = ptr->head;
     338             :                 ptr->foundEntryNumber = 0;
     339             :                 return ptr->head->data;
     340             :         }
     341             : 
     342             :         entry = ptr->foundEntry;
     343             :         if ( itemNumber < (u32) ptr->foundEntryNumber ) {
     344             :                 for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
     345             :                         entry = entry->prev;
     346             :                 }
     347             :         } else {
     348             :                 for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
     349             :                         entry = entry->next;
     350             :                 }
     351             :         }
     352             :         ptr->foundEntryNumber = itemNumber;
     353             :         ptr->foundEntry = entry;
     354             :         return (void *) entry->data;
     355             : }
     356             : 
     357             : GF_EXPORT
     358             : void *gf_list_last(GF_List *ptr)
     359             : {
     360             :         if(!ptr || !ptr->tail) return NULL;
     361             :         return ptr->tail->data;
     362             : }
     363             : 
     364             : GF_EXPORT
     365             : GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
     366             : {
     367             :         ItemSlot *tmp;
     368             :         u32 i;
     369             : 
     370             :         /* !! if head is null (empty list)*/
     371             :         if ( (! ptr) || (! ptr->head) || (ptr->head && !ptr->entryCount) || (itemNumber >= ptr->entryCount) )
     372             :                 return GF_BAD_PARAM;
     373             : 
     374             :         /*we delete the head*/
     375             :         if (! itemNumber) {
     376             :                 tmp = ptr->head;
     377             :                 ptr->head = ptr->head->next;
     378             : 
     379             :                 ptr->entryCount --;
     380             :                 ptr->foundEntry = ptr->head;
     381             :                 ptr->foundEntryNumber = 0;
     382             :                 gf_free(tmp);
     383             : 
     384             :                 /*that was the last entry, reset the tail*/
     385             :                 if (!ptr->entryCount) {
     386             :                         ptr->tail = ptr->head = ptr->foundEntry = NULL;
     387             :                         ptr->foundEntryNumber = -1;
     388             :                 } else {
     389             :                         ptr->head->prev = NULL;
     390             :                 }
     391             :                 return GF_OK;
     392             :         }
     393             :         else if (itemNumber==ptr->entryCount-1) {
     394             :                 tmp = ptr->tail;
     395             :                 ptr->tail = tmp->prev;
     396             :                 ptr->tail->next = NULL;
     397             :                 ptr->entryCount--;
     398             :                 if (ptr->foundEntry==tmp) {
     399             :                         ptr->foundEntry = ptr->tail;
     400             :                         ptr->foundEntryNumber = ptr->entryCount-1;
     401             :                 }
     402             :                 gf_free(tmp);
     403             :                 return GF_OK;
     404             :         }
     405             : 
     406             :         tmp = ptr->foundEntry;
     407             :         if ( itemNumber < (u32) ptr->foundEntryNumber ) {
     408             :                 for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
     409             :                         tmp = tmp->prev;
     410             :                 }
     411             :         } else {
     412             :                 for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
     413             :                         tmp = tmp->next;
     414             :                 }
     415             :         }
     416             :         tmp->prev->next = tmp->next;
     417             :         tmp->next->prev = tmp->prev;
     418             :         if (tmp==ptr->foundEntry) ptr->foundEntry = tmp->next;
     419             :         gf_free(tmp);
     420             :         ptr->entryCount--;
     421             :         return GF_OK;
     422             : }
     423             : 
     424             : GF_EXPORT
     425             : GF_Err gf_list_rem_last(GF_List *ptr)
     426             : {
     427             :         return gf_list_rem(ptr, ptr->entryCount-1);
     428             : }
     429             : 
     430             : GF_EXPORT
     431             : GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
     432             : {
     433             :         u32 i;
     434             :         ItemSlot *tmp, *tmp2;
     435             : 
     436             :         if (!ptr || !item) return GF_BAD_PARAM;
     437             :         /*if last entry or first of an empty array...*/
     438             :         if (position >= ptr->entryCount) return gf_list_add(ptr, item);
     439             :         tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
     440             :         tmp2->data = item;
     441             :         tmp2->next = tmp2->prev = NULL;
     442             :         /*special case for the head*/
     443             :         if (position == 0) {
     444             :                 ptr->head->prev = tmp2;
     445             :                 tmp2->next = ptr->head;
     446             :                 ptr->head = tmp2;
     447             :                 ptr->entryCount ++;
     448             :                 ptr->foundEntry = tmp2;
     449             :                 ptr->foundEntryNumber = 0;
     450             :                 return GF_OK;
     451             :         }
     452             : 
     453             :         tmp = ptr->foundEntry;
     454             :         if ( position < (u32) ptr->foundEntryNumber ) {
     455             :                 for (i = ptr->foundEntryNumber; i >= position; i-- ) {
     456             :                         tmp = tmp->prev;
     457             :                 }
     458             :                 tmp = tmp->prev;
     459             :         } else {
     460             :                 for (i = ptr->foundEntryNumber; i < position; i++ ) {
     461             :                         tmp = tmp->next;
     462             :                 }
     463             :         }
     464             :         tmp2->next = tmp->next;
     465             :         tmp2->next->prev = tmp2;
     466             :         tmp2->prev = tmp;
     467             :         tmp2->prev->next = tmp2;
     468             :         ptr->entryCount ++;
     469             :         ptr->foundEntry = tmp2;
     470             :         ptr->foundEntryNumber = position;
     471             :         return GF_OK;
     472             : }
     473             : 
     474             : #elif defined(GF_LIST_ARRAY)
     475             : 
     476             : struct _tag_array
     477             : {
     478             :         void **slots;
     479             :         u32 entryCount;
     480             : };
     481             : 
     482             : 
     483             : GF_EXPORT
     484             : GF_List * gf_list_new()
     485             : {
     486             :         GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
     487             :         if (! nlist) return NULL;
     488             :         nlist->slots = NULL;
     489             :         nlist->entryCount = 0;
     490             :         return nlist;
     491             : }
     492             : 
     493             : GF_EXPORT
     494             : void gf_list_del(GF_List *ptr)
     495             : {
     496             :         if (!ptr) return;
     497             :         gf_free(ptr->slots);
     498             :         gf_free(ptr);
     499             : }
     500             : 
     501             : GF_EXPORT
     502             : GF_Err gf_list_add(GF_List *ptr, void* item)
     503             : {
     504             :         if (! ptr) return GF_BAD_PARAM;
     505             : 
     506             :         ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*));
     507             :         if (!ptr->slots) {
     508             :                 return GF_OUT_OF_MEM;
     509             :         }
     510             :         ptr->slots[ptr->entryCount] = item;
     511             :         ptr->entryCount ++;
     512             :         return GF_OK;
     513             : }
     514             : 
     515             : GF_EXPORT
     516             : u32 gf_list_count(GF_List *ptr)
     517             : {
     518             :         return ptr ? ptr->entryCount : 0;
     519             : }
     520             : 
     521             : GF_EXPORT
     522             : void *gf_list_get(GF_List *ptr, u32 itemNumber)
     523             : {
     524             :         if(!ptr || (itemNumber >= ptr->entryCount)) return NULL;
     525             :         return ptr->slots[itemNumber];
     526             : }
     527             : 
     528             : GF_EXPORT
     529             : void *gf_list_last(GF_List *ptr)
     530             : {
     531             :         if(!ptr || !ptr->entryCount) return NULL;
     532             :         return ptr->slots[ptr->entryCount-1];
     533             : }
     534             : 
     535             : 
     536             : /*WARNING: itemNumber is from 0 to entryCount - 1*/
     537             : GF_EXPORT
     538             : GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
     539             : {
     540             :         u32 i;
     541             :         if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
     542             :         i = ptr->entryCount - itemNumber - 1;
     543             :         if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
     544             :         ptr->slots[ptr->entryCount-1] = NULL;
     545             :         ptr->entryCount -= 1;
     546             :         ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
     547             :         return GF_OK;
     548             : }
     549             : 
     550             : GF_EXPORT
     551             : GF_Err gf_list_rem_last(GF_List *ptr)
     552             : {
     553             :         if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
     554             :         ptr->entryCount -= 1;
     555             :         ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
     556             :         return GF_OK;
     557             : }
     558             : 
     559             : 
     560             : /*WARNING: position is from 0 to entryCount - 1*/
     561             : GF_EXPORT
     562             : GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
     563             : {
     564             :         u32 i;
     565             :         if (!ptr || !item) return GF_BAD_PARAM;
     566             :         /*if last entry or first of an empty array...*/
     567             :         if (position >= ptr->entryCount) return gf_list_add(ptr, item);
     568             :         ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*));
     569             :         i = ptr->entryCount - position;
     570             :         memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
     571             :         ptr->entryCount++;
     572             :         ptr->slots[position] = item;
     573             :         return GF_OK;
     574             : }
     575             : 
     576             : GF_EXPORT
     577             : void gf_list_reset(GF_List *ptr)
     578             : {
     579             :         if (ptr) {
     580             :                 ptr->entryCount = 0;
     581             :                 gf_free(ptr->slots);
     582             :                 ptr->slots = NULL;
     583             :         }
     584             : }
     585             : 
     586             : #else   /*GF_LIST_ARRAY_GROW*/
     587             : 
     588             : 
     589             : struct _tag_array
     590             : {
     591             :         void **slots;
     592             :         u32 entryCount;
     593             :         u32 allocSize;
     594             : };
     595             : 
     596             : GF_EXPORT
     597      963155 : GF_List * gf_list_new()
     598             : {
     599             :         GF_List *nlist;
     600             : 
     601      963155 :         nlist = (GF_List *) gf_malloc(sizeof(GF_List));
     602      963155 :         if (! nlist) return NULL;
     603             : 
     604      963155 :         nlist->slots = NULL;
     605      963155 :         nlist->entryCount = 0;
     606      963155 :         nlist->allocSize = 0;
     607      963155 :         return nlist;
     608             : }
     609             : 
     610             : GF_EXPORT
     611     1006031 : void gf_list_del(GF_List *ptr)
     612             : {
     613     1006031 :         if (!ptr) return;
     614      962969 :         gf_free(ptr->slots);
     615      962969 :         gf_free(ptr);
     616             : }
     617             : 
     618      710269 : static void realloc_chain(GF_List *ptr)
     619             : {
     620      710269 :         GF_LIST_REALLOC(ptr->allocSize);
     621      710269 :         ptr->slots = (void**)gf_realloc(ptr->slots, ptr->allocSize*sizeof(void*));
     622      710269 : }
     623             : 
     624             : GF_EXPORT
     625     5342983 : GF_Err gf_list_add(GF_List *ptr, void* item)
     626             : {
     627     5342983 :         if (! ptr) return GF_BAD_PARAM;
     628     5342961 :         if (! item)
     629             :                 return GF_BAD_PARAM;
     630     5341720 :         if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
     631     5341720 :         if (!ptr->slots) return GF_OUT_OF_MEM;
     632             : 
     633     5341720 :         ptr->slots[ptr->entryCount] = item;
     634     5341720 :         ptr->entryCount ++;
     635     5341720 :         return GF_OK;
     636             : }
     637             : 
     638             : GF_EXPORT
     639    64805182 : u32 gf_list_count(const GF_List *ptr)
     640             : {
     641    64805182 :         if (!ptr) return 0;
     642    64647296 :         return ptr->entryCount;
     643             : }
     644             : 
     645             : GF_EXPORT
     646   343395434 : void *gf_list_get(GF_List *ptr, u32 itemNumber)
     647             : {
     648   343395434 :         if(!ptr || (itemNumber >= ptr->entryCount))
     649             :                 return NULL;
     650   328620508 :         return ptr->slots[itemNumber];
     651             : }
     652             : 
     653             : GF_EXPORT
     654     5218727 : void *gf_list_last(GF_List *ptr)
     655             : {
     656     5218727 :         if(!ptr || !ptr->entryCount) return NULL;
     657     5195955 :         return ptr->slots[ptr->entryCount-1];
     658             : }
     659             : 
     660             : 
     661             : /*WARNING: itemNumber is from 0 to entryCount - 1*/
     662             : GF_EXPORT
     663     3385618 : GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
     664             : {
     665             :         u32 i;
     666     3385618 :         if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
     667     3385615 :         if (ptr->entryCount < itemNumber) return GF_BAD_PARAM;
     668             :         
     669     3385615 :         i = ptr->entryCount - itemNumber - 1;
     670     3385615 :         if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
     671     3385615 :         ptr->slots[ptr->entryCount-1] = NULL;
     672     3385615 :         ptr->entryCount -= 1;
     673     3385615 :         return GF_OK;
     674             : }
     675             : 
     676             : GF_EXPORT
     677     1673026 : GF_Err gf_list_rem_last(GF_List *ptr)
     678             : {
     679     1673026 :         if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
     680     1672925 :         ptr->slots[ptr->entryCount-1] = NULL;
     681     1672925 :         ptr->entryCount -= 1;
     682     1672925 :         return GF_OK;
     683             : }
     684             : 
     685             : /*WARNING: position is from 0 to entryCount - 1*/
     686             : GF_EXPORT
     687       58661 : GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
     688             : {
     689             :         u32 i;
     690       58661 :         if (!ptr || !item) return GF_BAD_PARAM;
     691             :         /*if last entry or first of an empty array...*/
     692       58660 :         if (position >= ptr->entryCount) return gf_list_add(ptr, item);
     693       56543 :         if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
     694             : 
     695       56543 :         i = ptr->entryCount - position;
     696       56543 :         memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
     697       56543 :         ptr->entryCount++;
     698       56543 :         ptr->slots[position] = item;
     699       56543 :         return GF_OK;
     700             : }
     701             : 
     702             : GF_EXPORT
     703       92613 : void gf_list_reset(GF_List *ptr)
     704             : {
     705       92613 :         if (ptr) ptr->entryCount = 0;
     706       92613 : }
     707             : 
     708             : #endif
     709             : 
     710             : GF_EXPORT
     711     1670092 : s32 gf_list_find(GF_List *ptr, void *item)
     712             : {
     713             :         u32 i, count;
     714     1670092 :         count = gf_list_count(ptr);
     715    27815167 :         for (i=0; i<count; i++) {
     716    27171784 :                 if (gf_list_get(ptr, i) == item) return (s32) i;
     717             :         }
     718             :         return -1;
     719             : }
     720             : 
     721             : GF_EXPORT
     722      454329 : s32 gf_list_del_item(GF_List *ptr, void *item)
     723             : {
     724      454329 :         s32 i = gf_list_find(ptr, item);
     725      454329 :         if (i>=0) gf_list_rem(ptr, (u32) i);
     726      454329 :         return i;
     727             : }
     728             : 
     729             : GF_EXPORT
     730    53393396 : void *gf_list_enum(GF_List *ptr, u32 *pos)
     731             : {
     732             :         void *res;
     733    53393396 :         if (!ptr || !pos) return NULL;
     734    53325720 :         res = gf_list_get(ptr, *pos);
     735    53325720 :         (*pos)++;
     736    53325720 :         return res;
     737             : }
     738             : 
     739             : //unused
     740             : #if 0
     741             : GF_EXPORT
     742             : void *gf_list_rev_enum(GF_List *ptr, u32 *pos) {
     743             :         void *res;
     744             :         if (!ptr || !pos) return NULL;
     745             :         res = gf_list_get(ptr, gf_list_count (ptr) - *pos - 1 );
     746             :         (*pos)++;
     747             :         return res;
     748             : }
     749             : #endif
     750             : 
     751             : GF_EXPORT
     752          56 : GF_Err gf_list_swap(GF_List *l1, GF_List *l2)
     753             : {
     754             :         GF_Err e;
     755          56 :         u32 count = gf_list_count(l1);
     756          56 :         if (!l1 || !l2) return GF_BAD_PARAM;
     757          55 :         if (l1 == l2) return GF_OK;
     758             : 
     759         256 :         while (gf_list_count(l2)) {
     760         201 :                 void *ptr = gf_list_get(l2, 0);
     761         201 :                 e = gf_list_rem(l2, 0);
     762         201 :                 if (e) return e;
     763         201 :                 e = gf_list_add(l1, ptr);
     764         201 :                 if (e) return e;
     765             :         }
     766         316 :         while (count) {
     767         261 :                 void *ptr = gf_list_get(l1, 0);
     768         261 :                 e = gf_list_rem(l1, 0);
     769         261 :                 if (e) return e;
     770         261 :                 count--;
     771         261 :                 e = gf_list_add(l2, ptr);
     772         261 :                 if (e) return e;
     773             :         }
     774             :         return GF_OK;
     775             : }
     776             : 
     777             : GF_EXPORT
     778          64 : GF_Err gf_list_transfer(GF_List *dst, GF_List *src)
     779             : {
     780             :         GF_Err e;
     781          64 :         if (!dst || !src) return GF_BAD_PARAM;
     782          64 :         if (dst == src) return GF_OK;
     783             : 
     784         169 :         while (gf_list_count(src)) {
     785         105 :                 void *ptr = gf_list_pop_front(src);
     786         105 :                 if (!ptr) return GF_BAD_PARAM;
     787         105 :                 e = gf_list_add(dst, ptr);
     788         105 :                 if (e) return e;
     789             :         }
     790             :         return GF_OK;
     791             : }
     792             : 
     793             : GF_EXPORT
     794          11 : GF_List* gf_list_clone(GF_List *ptr) {
     795             :         GF_List* new_list;
     796          11 :         u32 i = 0;
     797             :         void* item;
     798          11 :         if (!ptr) return NULL;
     799          11 :         new_list = gf_list_new();
     800          40 :         while ((item = gf_list_enum(ptr, &i)))
     801          18 :                 gf_list_add(new_list, item);
     802             : 
     803             :         return new_list;
     804             : }
     805             : 
     806             : //unused
     807             : #if 0
     808             : void gf_list_reverse(GF_List *ptr) {
     809             :         GF_List* saved_order;
     810             :         void* item;
     811             :         u32 i = 0;
     812             :         if (!ptr) return;
     813             :         saved_order = gf_list_clone(ptr);
     814             :         gf_list_reset(ptr);
     815             : 
     816             :         while ((item = gf_list_enum(saved_order, &i))) {
     817             :                 gf_list_insert(ptr, item, 0);
     818             :         }
     819             : 
     820             :         gf_list_del(saved_order);
     821             : }
     822             : #endif
     823             : 
     824             : GF_EXPORT
     825       17596 : void* gf_list_pop_front(GF_List *ptr) {
     826             :         void * item;
     827       17596 :         if (!ptr) return NULL;
     828             : 
     829       17596 :         item = gf_list_get(ptr, 0);
     830       17596 :         gf_list_rem(ptr, 0);
     831             : 
     832       17596 :         return item;
     833             : }
     834             : 
     835             : GF_EXPORT
     836     1552232 : void* gf_list_pop_back(GF_List *ptr) {
     837             :         void * item;
     838     1552232 :         if (!ptr) return NULL;
     839             : 
     840     1552235 :         item = gf_list_last(ptr);
     841     1552235 :         gf_list_rem_last(ptr);
     842             : 
     843     1552234 :         return item;
     844             : }

Generated by: LCOV version 1.13