summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plist.c80
-rw-r--r--src/ptrarray.c42
-rw-r--r--src/ptrarray.h13
3 files changed, 113 insertions, 22 deletions
diff --git a/src/plist.c b/src/plist.c
index 70386bc..f22a8a0 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -28,6 +28,7 @@
28#include <stdio.h> 28#include <stdio.h>
29#include <math.h> 29#include <math.h>
30#include <assert.h> 30#include <assert.h>
31#include <limits.h>
31 32
32#ifdef WIN32 33#ifdef WIN32
33#include <windows.h> 34#include <windows.h>
@@ -37,6 +38,7 @@
37 38
38#include <node.h> 39#include <node.h>
39#include <hashtable.h> 40#include <hashtable.h>
41#include <ptrarray.h>
40 42
41extern void plist_xml_init(void); 43extern void plist_xml_init(void);
42extern void plist_xml_deinit(void); 44extern void plist_xml_deinit(void);
@@ -190,6 +192,9 @@ void plist_free_data(plist_data_t data)
190 case PLIST_DATA: 192 case PLIST_DATA:
191 free(data->buff); 193 free(data->buff);
192 break; 194 break;
195 case PLIST_ARRAY:
196 ptr_array_free(data->hashtable);
197 break;
193 case PLIST_DICT: 198 case PLIST_DICT:
194 hash_table_destroy(data->hashtable); 199 hash_table_destroy(data->hashtable);
195 break; 200 break;
@@ -338,6 +343,20 @@ static void plist_copy_node(node_t *node, void *parent_node_ptr)
338 case PLIST_STRING: 343 case PLIST_STRING:
339 newdata->strval = strdup((char *) data->strval); 344 newdata->strval = strdup((char *) data->strval);
340 break; 345 break;
346 case PLIST_ARRAY:
347 if (data->hashtable) {
348 ptrarray_t* pa = ptr_array_new(((ptrarray_t*)data->hashtable)->capacity);
349 assert(pa);
350 plist_t current = NULL;
351 for (current = (plist_t)node_first_child(node);
352 pa && current;
353 current = (plist_t)node_next_sibling(current))
354 {
355 ptr_array_add(pa, current);
356 }
357 newdata->hashtable = pa;
358 }
359 break;
341 case PLIST_DICT: 360 case PLIST_DICT:
342 if (data->hashtable) { 361 if (data->hashtable) {
343 hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL); 362 hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
@@ -392,9 +411,14 @@ PLIST_API uint32_t plist_array_get_size(plist_t node)
392PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n) 411PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n)
393{ 412{
394 plist_t ret = NULL; 413 plist_t ret = NULL;
395 if (node && PLIST_ARRAY == plist_get_node_type(node)) 414 if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
396 { 415 {
397 ret = (plist_t)node_nth_child(node, n); 416 ptrarray_t *pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
417 if (pa) {
418 ret = (plist_t)ptr_array_index(pa, n);
419 } else {
420 ret = (plist_t)node_nth_child(node, n);
421 }
398 } 422 }
399 return ret; 423 return ret;
400} 424}
@@ -409,19 +433,46 @@ PLIST_API uint32_t plist_array_get_item_index(plist_t node)
409 return 0; 433 return 0;
410} 434}
411 435
436static void _plist_array_post_insert(plist_t node, plist_t item, long n)
437{
438 ptrarray_t *pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
439 if (pa) {
440 /* store pointer to item in array */
441 ptr_array_insert(pa, item, n);
442 } else {
443 if (((node_t*)node)->count > 100) {
444 /* make new lookup array */
445 pa = ptr_array_new(128);
446 plist_t current = NULL;
447 for (current = (plist_t)node_first_child(node);
448 pa && current;
449 current = (plist_t)node_next_sibling(current))
450 {
451 ptr_array_add(pa, current);
452 }
453 ((plist_data_t)((node_t*)node)->data)->hashtable = pa;
454 }
455 }
456}
457
412PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n) 458PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
413{ 459{
414 if (node && PLIST_ARRAY == plist_get_node_type(node)) 460 if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
415 { 461 {
416 plist_t old_item = plist_array_get_item(node, n); 462 plist_t old_item = plist_array_get_item(node, n);
417 if (old_item) 463 if (old_item)
418 { 464 {
419 int idx = plist_free_node(old_item); 465 int idx = plist_free_node(old_item);
420 if (idx < 0) { 466 assert(idx >= 0);
421 node_attach(node, item); 467 if (idx < 0) {
422 } else { 468 return;
423 node_insert(node, idx, item); 469 } else {
424 } 470 node_insert(node, idx, item);
471 ptrarray_t* pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
472 if (pa) {
473 ptr_array_set(pa, item, idx);
474 }
475 }
425 } 476 }
426 } 477 }
427 return; 478 return;
@@ -432,26 +483,32 @@ PLIST_API void plist_array_append_item(plist_t node, plist_t item)
432 if (node && PLIST_ARRAY == plist_get_node_type(node)) 483 if (node && PLIST_ARRAY == plist_get_node_type(node))
433 { 484 {
434 node_attach(node, item); 485 node_attach(node, item);
486 _plist_array_post_insert(node, item, -1);
435 } 487 }
436 return; 488 return;
437} 489}
438 490
439PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) 491PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
440{ 492{
441 if (node && PLIST_ARRAY == plist_get_node_type(node)) 493 if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
442 { 494 {
443 node_insert(node, n, item); 495 node_insert(node, n, item);
496 _plist_array_post_insert(node, item, (long)n);
444 } 497 }
445 return; 498 return;
446} 499}
447 500
448PLIST_API void plist_array_remove_item(plist_t node, uint32_t n) 501PLIST_API void plist_array_remove_item(plist_t node, uint32_t n)
449{ 502{
450 if (node && PLIST_ARRAY == plist_get_node_type(node)) 503 if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
451 { 504 {
452 plist_t old_item = plist_array_get_item(node, n); 505 plist_t old_item = plist_array_get_item(node, n);
453 if (old_item) 506 if (old_item)
454 { 507 {
508 ptrarray_t* pa = ((plist_data_t)((node_t*)node)->data)->hashtable;
509 if (pa) {
510 ptr_array_remove(pa, n);
511 }
455 plist_free(old_item); 512 plist_free(old_item);
456 } 513 }
457 } 514 }
@@ -586,8 +643,9 @@ PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
586 plist_t key_node = NULL; 643 plist_t key_node = NULL;
587 if (old_item) { 644 if (old_item) {
588 int idx = plist_free_node(old_item); 645 int idx = plist_free_node(old_item);
646 assert(idx >= 0);
589 if (idx < 0) { 647 if (idx < 0) {
590 node_attach(node, item); 648 return;
591 } else { 649 } else {
592 node_insert(node, idx, item); 650 node_insert(node, idx, item);
593 } 651 }
diff --git a/src/ptrarray.c b/src/ptrarray.c
index eb17d28..bcffb77 100644
--- a/src/ptrarray.c
+++ b/src/ptrarray.c
@@ -2,7 +2,7 @@
2 * ptrarray.c 2 * ptrarray.c
3 * simple pointer array implementation 3 * simple pointer array implementation
4 * 4 *
5 * Copyright (c) 2011 Nikias Bassen, All Rights Reserved. 5 * Copyright (c) 2011-2019 Nikias Bassen, All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21#include "ptrarray.h" 21#include "ptrarray.h"
22#include <string.h>
22 23
23ptrarray_t *ptr_array_new(int capacity) 24ptrarray_t *ptr_array_new(int capacity)
24{ 25{
@@ -39,22 +40,51 @@ void ptr_array_free(ptrarray_t *pa)
39 free(pa); 40 free(pa);
40} 41}
41 42
42void ptr_array_add(ptrarray_t *pa, void *data) 43void ptr_array_insert(ptrarray_t *pa, void *data, long array_index)
43{ 44{
44 if (!pa || !pa->pdata || !data) return; 45 if (!pa || !pa->pdata || !data) return;
45 size_t remaining = pa->capacity-pa->len; 46 long remaining = pa->capacity-pa->len;
46 if (remaining == 0) { 47 if (remaining == 0) {
47 pa->pdata = realloc(pa->pdata, sizeof(void*) * (pa->capacity + pa->capacity_step)); 48 pa->pdata = realloc(pa->pdata, sizeof(void*) * (pa->capacity + pa->capacity_step));
48 pa->capacity += pa->capacity_step; 49 pa->capacity += pa->capacity_step;
49 } 50 }
50 pa->pdata[pa->len] = data; 51 if (array_index < 0 || array_index >= pa->len) {
52 pa->pdata[pa->len] = data;
53 } else {
54 memmove(&pa->pdata[array_index+1], &pa->pdata[array_index], (pa->len-array_index) * sizeof(void*));
55 pa->pdata[array_index] = data;
56 }
51 pa->len++; 57 pa->len++;
52} 58}
53 59
54void* ptr_array_index(ptrarray_t *pa, size_t array_index) 60void ptr_array_add(ptrarray_t *pa, void *data)
61{
62 ptr_array_insert(pa, data, -1);
63}
64
65void ptr_array_remove(ptrarray_t *pa, long array_index)
66{
67 if (!pa || !pa->pdata || array_index < 0) return;
68 if (pa->len == 0 || array_index >= pa->len) return;
69 if (pa->len == 1) {
70 pa->pdata[0] = NULL;
71 } else {
72 memmove(&pa->pdata[array_index], &pa->pdata[array_index+1], (pa->len-array_index-1) * sizeof(void*));
73 }
74 pa->len--;
75}
76
77void ptr_array_set(ptrarray_t *pa, void *data, long array_index)
78{
79 if (!pa || !pa->pdata || array_index < 0) return;
80 if (pa->len == 0 || array_index >= pa->len) return;
81 pa->pdata[array_index] = data;
82}
83
84void* ptr_array_index(ptrarray_t *pa, long array_index)
55{ 85{
56 if (!pa) return NULL; 86 if (!pa) return NULL;
57 if (array_index >= pa->len) { 87 if (array_index < 0 || array_index >= pa->len) {
58 return NULL; 88 return NULL;
59 } 89 }
60 return pa->pdata[array_index]; 90 return pa->pdata[array_index];
diff --git a/src/ptrarray.h b/src/ptrarray.h
index e8a3c88..2c6136a 100644
--- a/src/ptrarray.h
+++ b/src/ptrarray.h
@@ -2,7 +2,7 @@
2 * ptrarray.h 2 * ptrarray.h
3 * header file for simple pointer array implementation 3 * header file for simple pointer array implementation
4 * 4 *
5 * Copyright (c) 2011 Nikias Bassen, All Rights Reserved. 5 * Copyright (c) 2011-2019 Nikias Bassen, All Rights Reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
@@ -24,13 +24,16 @@
24 24
25typedef struct ptrarray_t { 25typedef struct ptrarray_t {
26 void **pdata; 26 void **pdata;
27 size_t len; 27 long len;
28 size_t capacity; 28 long capacity;
29 size_t capacity_step; 29 long capacity_step;
30} ptrarray_t; 30} ptrarray_t;
31 31
32ptrarray_t *ptr_array_new(int capacity); 32ptrarray_t *ptr_array_new(int capacity);
33void ptr_array_free(ptrarray_t *pa); 33void ptr_array_free(ptrarray_t *pa);
34void ptr_array_add(ptrarray_t *pa, void *data); 34void ptr_array_add(ptrarray_t *pa, void *data);
35void* ptr_array_index(ptrarray_t *pa, size_t index); 35void ptr_array_insert(ptrarray_t *pa, void *data, long index);
36void ptr_array_remove(ptrarray_t *pa, long index);
37void ptr_array_set(ptrarray_t *pa, void *data, long index);
38void* ptr_array_index(ptrarray_t *pa, long index);
36#endif 39#endif