Coverage Report

Created: 2026-05-30 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/utils/list.c
Line
Count
Source
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
4.03M
#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_List * gf_list_new_prealloc(u32 nb_prealloc)
281
{
282
  if (!nb_prealloc) return NULL;
283
  return gf_list_new();
284
}
285
286
GF_EXPORT
287
void gf_list_del(GF_List *ptr)
288
{
289
  if (!ptr) return;
290
  while (ptr->entryCount) {
291
    gf_list_rem(ptr, 0);
292
  }
293
  gf_free(ptr);
294
}
295
296
GF_EXPORT
297
void gf_list_reset(GF_List *ptr)
298
{
299
  while (ptr && ptr->entryCount) gf_list_rem(ptr, 0);
300
}
301
302
GF_EXPORT
303
GF_Err gf_list_add(GF_List *ptr, void* item)
304
{
305
  ItemSlot *entry;
306
  if (! ptr) return GF_BAD_PARAM;
307
  entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
308
  if (!entry) return GF_OUT_OF_MEM;
309
  entry->data = item;
310
  entry->next = entry->prev = NULL;
311
312
  if (! ptr->head) {
313
    ptr->head = entry;
314
    ptr->entryCount = 1;
315
  } else {
316
    ptr->entryCount += 1;
317
    entry->prev = ptr->tail;
318
    ptr->tail->next = entry;
319
  }
320
  ptr->tail = entry;
321
  ptr->foundEntryNumber = ptr->entryCount - 1;
322
  ptr->foundEntry = entry;
323
  return GF_OK;
324
}
325
326
327
GF_EXPORT
328
u32 gf_list_count(GF_List *ptr)
329
{
330
  if (! ptr) return 0;
331
  return ptr->entryCount;
332
}
333
334
GF_EXPORT
335
void *gf_list_get(GF_List *ptr, u32 itemNumber)
336
{
337
  ItemSlot *entry;
338
  u32 i;
339
340
  if (!ptr || !ptr->head || (itemNumber >= ptr->entryCount) ) return NULL;
341
342
  if (!itemNumber) {
343
    ptr->foundEntry = ptr->head;
344
    ptr->foundEntryNumber = 0;
345
    return ptr->head->data;
346
  }
347
348
  entry = ptr->foundEntry;
349
  if ( itemNumber < (u32) ptr->foundEntryNumber ) {
350
    for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
351
      entry = entry->prev;
352
    }
353
  } else {
354
    for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
355
      entry = entry->next;
356
    }
357
  }
358
  ptr->foundEntryNumber = itemNumber;
359
  ptr->foundEntry = entry;
360
  return (void *) entry->data;
361
}
362
363
GF_EXPORT
364
void *gf_list_last(GF_List *ptr)
365
{
366
  if(!ptr || !ptr->tail) return NULL;
367
  return ptr->tail->data;
368
}
369
370
GF_EXPORT
371
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
372
{
373
  ItemSlot *tmp;
374
  u32 i;
375
376
  /* !! if head is null (empty list)*/
377
  if ( (! ptr) || (! ptr->head) || (ptr->head && !ptr->entryCount) || (itemNumber >= ptr->entryCount) )
378
    return GF_BAD_PARAM;
379
380
  /*we delete the head*/
381
  if (! itemNumber) {
382
    tmp = ptr->head;
383
    ptr->head = ptr->head->next;
384
385
    ptr->entryCount --;
386
    ptr->foundEntry = ptr->head;
387
    ptr->foundEntryNumber = 0;
388
    gf_free(tmp);
389
390
    /*that was the last entry, reset the tail*/
391
    if (!ptr->entryCount) {
392
      ptr->tail = ptr->head = ptr->foundEntry = NULL;
393
      ptr->foundEntryNumber = -1;
394
    } else {
395
      ptr->head->prev = NULL;
396
    }
397
    return GF_OK;
398
  }
399
  else if (itemNumber==ptr->entryCount-1) {
400
    tmp = ptr->tail;
401
    ptr->tail = tmp->prev;
402
    ptr->tail->next = NULL;
403
    ptr->entryCount--;
404
    if (ptr->foundEntry==tmp) {
405
      ptr->foundEntry = ptr->tail;
406
      ptr->foundEntryNumber = ptr->entryCount-1;
407
    }
408
    gf_free(tmp);
409
    return GF_OK;
410
  }
411
412
  tmp = ptr->foundEntry;
413
  if ( itemNumber < (u32) ptr->foundEntryNumber ) {
414
    for (i = ptr->foundEntryNumber; i > itemNumber; i-- ) {
415
      tmp = tmp->prev;
416
    }
417
  } else {
418
    for (i = ptr->foundEntryNumber; i < itemNumber; i++ ) {
419
      tmp = tmp->next;
420
    }
421
  }
422
  tmp->prev->next = tmp->next;
423
  tmp->next->prev = tmp->prev;
424
  if (tmp==ptr->foundEntry) ptr->foundEntry = tmp->next;
425
  gf_free(tmp);
426
  ptr->entryCount--;
427
  return GF_OK;
428
}
429
430
GF_EXPORT
431
GF_Err gf_list_rem_last(GF_List *ptr)
432
{
433
  return gf_list_rem(ptr, ptr->entryCount-1);
434
}
435
436
GF_EXPORT
437
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
438
{
439
  u32 i;
440
  ItemSlot *tmp, *tmp2;
441
442
  if (!ptr || !item) return GF_BAD_PARAM;
443
  /*if last entry or first of an empty array...*/
444
  if (position >= ptr->entryCount) return gf_list_add(ptr, item);
445
  tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot));
446
  tmp2->data = item;
447
  tmp2->next = tmp2->prev = NULL;
448
  /*special case for the head*/
449
  if (position == 0) {
450
    ptr->head->prev = tmp2;
451
    tmp2->next = ptr->head;
452
    ptr->head = tmp2;
453
    ptr->entryCount ++;
454
    ptr->foundEntry = tmp2;
455
    ptr->foundEntryNumber = 0;
456
    return GF_OK;
457
  }
458
459
  tmp = ptr->foundEntry;
460
  if ( position < (u32) ptr->foundEntryNumber ) {
461
    for (i = ptr->foundEntryNumber; i >= position; i-- ) {
462
      tmp = tmp->prev;
463
    }
464
    tmp = tmp->prev;
465
  } else {
466
    for (i = ptr->foundEntryNumber; i < position; i++ ) {
467
      tmp = tmp->next;
468
    }
469
  }
470
  tmp2->next = tmp->next;
471
  tmp2->next->prev = tmp2;
472
  tmp2->prev = tmp;
473
  tmp2->prev->next = tmp2;
474
  ptr->entryCount ++;
475
  ptr->foundEntry = tmp2;
476
  ptr->foundEntryNumber = position;
477
  return GF_OK;
478
}
479
480
#elif defined(GF_LIST_ARRAY)
481
482
struct _tag_array
483
{
484
  void **slots;
485
  u32 entryCount;
486
};
487
488
489
GF_EXPORT
490
GF_List * gf_list_new()
491
{
492
  GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List));
493
  if (! nlist) return NULL;
494
  nlist->slots = NULL;
495
  nlist->entryCount = 0;
496
  return nlist;
497
}
498
499
GF_List * gf_list_new_prealloc(u32 nb_prealloc)
500
{
501
  if (!nb_prealloc) return NULL;
502
  return gf_list_new();
503
}
504
GF_EXPORT
505
void gf_list_del(GF_List *ptr)
506
{
507
  if (!ptr) return;
508
  gf_free(ptr->slots);
509
  gf_free(ptr);
510
}
511
512
GF_EXPORT
513
GF_Err gf_list_add(GF_List *ptr, void* item)
514
{
515
  if (! ptr) return GF_BAD_PARAM;
516
517
  ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*));
518
  if (!ptr->slots) {
519
    return GF_OUT_OF_MEM;
520
  }
521
  ptr->slots[ptr->entryCount] = item;
522
  ptr->entryCount ++;
523
  return GF_OK;
524
}
525
526
GF_EXPORT
527
u32 gf_list_count(GF_List *ptr)
528
{
529
  return ptr ? ptr->entryCount : 0;
530
}
531
532
GF_EXPORT
533
void *gf_list_get(GF_List *ptr, u32 itemNumber)
534
{
535
  if(!ptr || (itemNumber >= ptr->entryCount)) return NULL;
536
  return ptr->slots[itemNumber];
537
}
538
539
GF_EXPORT
540
void *gf_list_last(GF_List *ptr)
541
{
542
  if(!ptr || !ptr->entryCount) return NULL;
543
  return ptr->slots[ptr->entryCount-1];
544
}
545
546
547
/*WARNING: itemNumber is from 0 to entryCount - 1*/
548
GF_EXPORT
549
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
550
{
551
  u32 i;
552
  if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
553
  i = ptr->entryCount - itemNumber - 1;
554
  if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
555
  ptr->slots[ptr->entryCount-1] = NULL;
556
  ptr->entryCount -= 1;
557
  ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
558
  return GF_OK;
559
}
560
561
GF_EXPORT
562
GF_Err gf_list_rem_last(GF_List *ptr)
563
{
564
  if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
565
  ptr->entryCount -= 1;
566
  ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount);
567
  return GF_OK;
568
}
569
570
571
/*WARNING: position is from 0 to entryCount - 1*/
572
GF_EXPORT
573
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
574
{
575
  u32 i;
576
  if (!ptr || !item) return GF_BAD_PARAM;
577
  /*if last entry or first of an empty array...*/
578
  if (position >= ptr->entryCount) return gf_list_add(ptr, item);
579
  ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*));
580
  i = ptr->entryCount - position;
581
  memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
582
  ptr->entryCount++;
583
  ptr->slots[position] = item;
584
  return GF_OK;
585
}
586
587
GF_EXPORT
588
void gf_list_reset(GF_List *ptr)
589
{
590
  if (ptr) {
591
    ptr->entryCount = 0;
592
    gf_free(ptr->slots);
593
    ptr->slots = NULL;
594
  }
595
}
596
597
#else /*GF_LIST_ARRAY_GROW*/
598
599
600
struct _tag_array
601
{
602
  void **slots;
603
  u32 entryCount;
604
  u32 allocSize;
605
};
606
607
GF_EXPORT
608
GF_List * gf_list_new()
609
3.96M
{
610
3.96M
  GF_List *nlist;
611
612
3.96M
  nlist = (GF_List *) gf_malloc(sizeof(GF_List));
613
3.96M
  if (! nlist) return NULL;
614
615
3.96M
  nlist->slots = NULL;
616
3.96M
  nlist->entryCount = 0;
617
3.96M
  nlist->allocSize = 0;
618
3.96M
  return nlist;
619
3.96M
}
620
621
GF_List * gf_list_new_prealloc(u32 nb_prealloc)
622
62.1k
{
623
62.1k
  if (!nb_prealloc) return NULL;
624
10.9k
  GF_List *nlist = gf_list_new();
625
10.9k
  if (nlist) {
626
10.9k
    nlist->allocSize = nb_prealloc;
627
10.9k
    nlist->slots = (void**)gf_malloc(nlist->allocSize*sizeof(void*));
628
10.9k
  }
629
10.9k
  return nlist;
630
62.1k
}
631
632
GF_EXPORT
633
void gf_list_del(GF_List *ptr)
634
4.22M
{
635
4.22M
  if (!ptr) return;
636
3.96M
  gf_free(ptr->slots);
637
3.96M
  gf_free(ptr);
638
3.96M
}
639
640
static void realloc_chain(GF_List *ptr)
641
4.03M
{
642
4.03M
  GF_LIST_REALLOC(ptr->allocSize);
643
4.03M
  ptr->slots = (void**)gf_realloc(ptr->slots, ptr->allocSize*sizeof(void*));
644
4.03M
}
645
646
GF_EXPORT
647
GF_Err gf_list_add(GF_List *ptr, void* item)
648
92.0M
{
649
92.0M
  if (! ptr) return GF_BAD_PARAM;
650
92.0M
  if (! item)
651
303
    return GF_BAD_PARAM;
652
92.0M
  if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
653
92.0M
  if (!ptr->slots) return GF_OUT_OF_MEM;
654
655
92.0M
  ptr->slots[ptr->entryCount] = item;
656
92.0M
  ptr->entryCount ++;
657
92.0M
  return GF_OK;
658
92.0M
}
659
660
GF_EXPORT
661
u32 gf_list_count(const GF_List *ptr)
662
63.2M
{
663
63.2M
  if (!ptr) return 0;
664
63.0M
  return ptr->entryCount;
665
63.2M
}
666
667
GF_EXPORT
668
void *gf_list_get(GF_List *ptr, u32 itemNumber)
669
462M
{
670
462M
  if(!ptr || (itemNumber >= ptr->entryCount))
671
2.36M
    return NULL;
672
460M
  return ptr->slots[itemNumber];
673
462M
}
674
675
GF_EXPORT
676
void *gf_list_last(GF_List *ptr)
677
13.5M
{
678
13.5M
  if(!ptr || !ptr->entryCount) return NULL;
679
13.0M
  return ptr->slots[ptr->entryCount-1];
680
13.5M
}
681
682
683
/*WARNING: itemNumber is from 0 to entryCount - 1*/
684
GF_EXPORT
685
GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber)
686
13.8M
{
687
13.8M
  u32 i;
688
13.8M
  if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
689
13.8M
  if (ptr->entryCount < itemNumber) return GF_BAD_PARAM;
690
691
13.8M
  i = ptr->entryCount - itemNumber - 1;
692
13.8M
  if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i);
693
13.8M
  ptr->slots[ptr->entryCount-1] = NULL;
694
13.8M
  ptr->entryCount -= 1;
695
13.8M
  return GF_OK;
696
13.8M
}
697
698
GF_EXPORT
699
GF_Err gf_list_rem_last(GF_List *ptr)
700
7.05M
{
701
7.05M
  if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM;
702
6.56M
  ptr->slots[ptr->entryCount-1] = NULL;
703
6.56M
  ptr->entryCount -= 1;
704
6.56M
  return GF_OK;
705
7.05M
}
706
707
/*WARNING: position is from 0 to entryCount - 1*/
708
GF_EXPORT
709
GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position)
710
6.35M
{
711
6.35M
  u32 i;
712
6.35M
  if (!ptr || !item) return GF_BAD_PARAM;
713
  /*if last entry or first of an empty array...*/
714
6.35M
  if (position >= ptr->entryCount) return gf_list_add(ptr, item);
715
6.34M
  if (ptr->allocSize==ptr->entryCount) realloc_chain(ptr);
716
717
6.34M
  i = ptr->entryCount - position;
718
6.34M
  memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i);
719
6.34M
  ptr->entryCount++;
720
6.34M
  ptr->slots[position] = item;
721
6.34M
  return GF_OK;
722
6.35M
}
723
724
GF_EXPORT
725
void gf_list_reset(GF_List *ptr)
726
263k
{
727
263k
  if (ptr) ptr->entryCount = 0;
728
263k
}
729
730
#endif
731
732
GF_EXPORT
733
s32 gf_list_find(GF_List *ptr, void *item)
734
9.15M
{
735
9.15M
  u32 i, count;
736
9.15M
  count = gf_list_count(ptr);
737
75.0M
  for (i=0; i<count; i++) {
738
72.2M
    if (gf_list_get(ptr, i) == item) return (s32) i;
739
72.2M
  }
740
2.73M
  return -1;
741
9.15M
}
742
743
GF_EXPORT
744
s32 gf_list_del_item(GF_List *ptr, void *item)
745
955k
{
746
955k
  s32 i = gf_list_find(ptr, item);
747
955k
  if (i>=0) gf_list_rem(ptr, (u32) i);
748
955k
  return i;
749
955k
}
750
751
GF_EXPORT
752
void *gf_list_enum(GF_List *ptr, u32 *pos)
753
20.8M
{
754
20.8M
  void *res;
755
20.8M
  if (!ptr || !pos) return NULL;
756
20.3M
  res = gf_list_get(ptr, *pos);
757
20.3M
  (*pos)++;
758
20.3M
  return res;
759
20.8M
}
760
761
//unused
762
#if 0
763
GF_EXPORT
764
void *gf_list_rev_enum(GF_List *ptr, u32 *pos) {
765
  void *res;
766
  if (!ptr || !pos) return NULL;
767
  res = gf_list_get(ptr, gf_list_count (ptr) - *pos - 1 );
768
  (*pos)++;
769
  return res;
770
}
771
#endif
772
773
GF_EXPORT
774
GF_Err gf_list_swap(GF_List *l1, GF_List *l2)
775
0
{
776
0
  GF_Err e;
777
0
  u32 count = gf_list_count(l1);
778
0
  if (!l1 || !l2) return GF_BAD_PARAM;
779
0
  if (l1 == l2) return GF_OK;
780
781
0
  while (gf_list_count(l2)) {
782
0
    void *ptr = gf_list_get(l2, 0);
783
0
    e = gf_list_rem(l2, 0);
784
0
    if (e) return e;
785
0
    e = gf_list_add(l1, ptr);
786
0
    if (e) return e;
787
0
  }
788
0
  while (count) {
789
0
    void *ptr = gf_list_get(l1, 0);
790
0
    e = gf_list_rem(l1, 0);
791
0
    if (e) return e;
792
0
    count--;
793
0
    e = gf_list_add(l2, ptr);
794
0
    if (e) return e;
795
0
  }
796
0
  return GF_OK;
797
0
}
798
799
GF_EXPORT
800
GF_Err gf_list_transfer(GF_List *dst, GF_List *src)
801
2.42k
{
802
2.42k
  GF_Err e;
803
2.42k
  if (!dst || !src) return GF_BAD_PARAM;
804
50
  if (dst == src) return GF_OK;
805
806
520
  while (gf_list_count(src)) {
807
470
    void *ptr = gf_list_pop_front(src);
808
470
    if (!ptr) return GF_BAD_PARAM;
809
470
    e = gf_list_add(dst, ptr);
810
470
    if (e) return e;
811
470
  }
812
50
  return GF_OK;
813
50
}
814
815
GF_EXPORT
816
11.0k
GF_List* gf_list_clone(GF_List *ptr) {
817
11.0k
  GF_List* new_list;
818
11.0k
  u32 i = 0;
819
11.0k
  void* item;
820
11.0k
  if (!ptr) return NULL;
821
11.0k
  new_list = gf_list_new();
822
11.0k
  while ((item = gf_list_enum(ptr, &i)))
823
0
    gf_list_add(new_list, item);
824
825
11.0k
  return new_list;
826
11.0k
}
827
828
//unused
829
#if 0
830
void gf_list_reverse(GF_List *ptr) {
831
  GF_List* saved_order;
832
  void* item;
833
  u32 i = 0;
834
  if (!ptr) return;
835
  saved_order = gf_list_clone(ptr);
836
  gf_list_reset(ptr);
837
838
  while ((item = gf_list_enum(saved_order, &i))) {
839
    gf_list_insert(ptr, item, 0);
840
  }
841
842
  gf_list_del(saved_order);
843
}
844
#endif
845
846
GF_EXPORT
847
594k
void* gf_list_pop_front(GF_List *ptr) {
848
594k
  void * item;
849
594k
  if (!ptr) return NULL;
850
851
434k
  item = gf_list_get(ptr, 0);
852
434k
  gf_list_rem(ptr, 0);
853
854
434k
  return item;
855
594k
}
856
857
GF_EXPORT
858
6.78M
void* gf_list_pop_back(GF_List *ptr) {
859
6.78M
  void * item;
860
6.78M
  if (!ptr) return NULL;
861
862
6.78M
  item = gf_list_last(ptr);
863
6.78M
  gf_list_rem_last(ptr);
864
865
6.78M
  return item;
866
6.78M
}