$darkmode
Libical API Documentation 4.0 STABLE VERSION Visit the v3.0 documentation
icalenumarray.c
Go to the documentation of this file.
1 /*======================================================================
2  FILE: icalenumarray.c
3  CREATOR: Ken Murchison 24 Aug 2022 <murch@fastmailteam.com>
4 
5  SPDX-FileCopyrightText: 2022, Fastmail Pty. Ltd. (https://fastmail.com)
6  SPDX-License-Identifier: LGPL-2.1-only OR MPL-2.0
7  ======================================================================*/
8 
14 #ifdef HAVE_CONFIG_H
15 #include <config.h>
16 #endif
17 
18 #include "icalenumarray.h"
19 #include "icalmemory.h"
20 
21 #include <string.h>
22 
23 size_t icalenumarray_size(const icalenumarray *array)
24 {
25  if (!array) {
26  return 0;
27  }
28  return array->num_elements;
29 }
30 
31 const icalenumarray_element *icalenumarray_element_at(icalenumarray *array, size_t position)
32 {
33  if (position >= icalenumarray_size(array)) {
34  return NULL;
35  }
36  return icalarray_element_at(array, position);
37 }
38 
39 static int enumcmp(const icalenumarray_element *a, const icalenumarray_element *b)
40 {
41  /* Sort X-values alphabetically, but last */
42  if (!a->xvalue && b->xvalue) {
43  return -1;
44  } else if (a->xvalue && !b->xvalue) {
45  return 1;
46  }
47 
48  if (a->val < b->val) {
49  return -1;
50  } else if (a->val > b->val) {
51  return 1;
52  }
53 
54  if (a->xvalue) {
55  return strcmp(a->xvalue, b->xvalue);
56  } else {
57  return 0;
58  }
59 }
60 
61 size_t icalenumarray_find(icalenumarray *array,
62  const icalenumarray_element *needle)
63 {
64  if (!array || !needle) {
65  return icalenumarray_size(array);
66  }
67 
68  size_t i;
69 
70  for (i = 0; i < array->num_elements; i++) {
71  const icalenumarray_element *e = icalarray_element_at(array, i);
72  if (!enumcmp(e, needle)) {
73  return i;
74  }
75  }
76 
77  return icalenumarray_size(array);
78 }
79 
80 void icalenumarray_append(icalenumarray *array, const icalenumarray_element *elem)
81 {
82  if (!array || !elem) {
83  return;
84  }
85 
86  /* coverity[resource_leak] */
87  char *val = (elem->xvalue ? icalmemory_strdup(elem->xvalue) : NULL);
88  icalenumarray_element copy = {elem->val, val};
89 
90  icalarray_append(array, &copy);
91 }
92 
93 void icalenumarray_add(icalenumarray *array, const icalenumarray_element *elem)
94 {
95  if (!array || !elem) {
96  return;
97  }
98 
99  if (icalenumarray_find(array, elem) >= icalenumarray_size(array)) {
100  icalenumarray_append(array, elem);
101  }
102 }
103 
104 void icalenumarray_remove_element_at(icalenumarray *array,
105  size_t position)
106 {
107  if (position >= icalenumarray_size(array)) {
108  return;
109  }
110 
111  icalenumarray_element *del = icalarray_element_at(array, position);
112 
113  icalmemory_free_buffer((char *)del->xvalue);
114  icalarray_remove_element_at(array, position);
115 }
116 
117 void icalenumarray_remove(icalenumarray *array, const icalenumarray_element *del)
118 {
119  if (!array || !del) {
120  return;
121  }
122 
123  size_t j = 0;
124 
125  for (size_t i = 0; i < array->num_elements; i++) {
126  const icalenumarray_element *elem = icalarray_element_at(array, i);
127  if (enumcmp(elem, del)) {
128  icalarray_set_element_at(array, elem, j++);
129  } else {
130  icalmemory_free_buffer((char *)elem->xvalue);
131  }
132  }
133 
134  array->num_elements = j;
135 }
136 
137 void icalenumarray_free(icalenumarray *array)
138 {
139  if (!array) {
140  return;
141  }
142 
143  for (size_t i = 0; i < icalenumarray_size(array); i++) {
145  icalmemory_free_buffer((char *)del->xvalue);
146  }
147 
148  icalarray_free(array);
149 }
150 
151 void icalenumarray_sort(icalenumarray *array)
152 {
153  if (!array) {
154  return;
155  }
156 
157  icalarray_sort(array, (int (*)(const void *, const void *))&enumcmp);
158 }
159 
160 icalenumarray *icalenumarray_clone(icalenumarray *array)
161 {
162  if (!array) {
163  return NULL;
164  }
165 
166  icalenumarray *clone = icalenumarray_new(array->increment_size);
167  size_t i;
168 
169  for (i = 0; i < array->num_elements; i++) {
171  }
172 
173  return clone;
174 }
void icalenumarray_remove(icalenumarray *array, const icalenumarray_element *del)
Removes all occurrences of an element.
void icalenumarray_remove_element_at(icalenumarray *array, size_t position)
Removes the element at an array position.
void icalarray_free(icalarray *array)
Definition: icalarray.c:104
Common memory management routines.
void icalenumarray_free(icalenumarray *array)
Frees this array's memory and all its elements.
void icalenumarray_add(icalenumarray *array, const icalenumarray_element *elem)
Appends an element to the array, omitting duplicates.
Definition: icalenumarray.c:93
void icalenumarray_append(icalenumarray *array, const icalenumarray_element *elem)
Appends an element to the array.
Definition: icalenumarray.c:80
void icalarray_set_element_at(icalarray *array, const void *element, size_t position)
Overwrites an existing element in an array with a new value.
Definition: icalarray.c:143
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
Definition: icalmemory.c:242
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition: icalmemory.c:355
size_t icalenumarray_size(const icalenumarray *array)
Indicates the count of elements stored in the array.
Definition: icalenumarray.c:23
icalenumarray * icalenumarray_clone(icalenumarray *array)
Clones the array and all its elements.
size_t icalenumarray_find(icalenumarray *array, const icalenumarray_element *needle)
Finds an element in the array.
Definition: icalenumarray.c:61
Defines the data structure for handling arrays of enums.
#define icalenumarray_new(increment_size)
Definition: icalenumarray.h:56
void icalarray_append(icalarray *array, const void *element)
Appends an element to an array.
Definition: icalarray.c:119
void * icalarray_element_at(icalarray *array, size_t position)
Access an array element.
Definition: icalarray.c:135
void icalenumarray_sort(icalenumarray *array)
Sorts the elements in the array in ascending order.
void icalarray_sort(icalarray *array, int(*compare)(const void *, const void *))
Sorts the elements of an icalarray using the given comparison function.
Definition: icalarray.c:182
void icalarray_remove_element_at(icalarray *array, size_t position)
Removes a given element from an array.
Definition: icalarray.c:148
const icalenumarray_element * icalenumarray_element_at(icalenumarray *array, size_t position)
Accesses an element stored in the array.
Definition: icalenumarray.c:31