Libical API Documentation 4.0 UNRELEASED Go to the stable 3.0 documentation
Loading...
Searching...
No Matches
vcardstructured.c
Go to the documentation of this file.
1/*======================================================================
2 FILE: vcardstructured.c
3 CREATOR: Ken Murchison 24 Aug 2022
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
13
14#ifdef HAVE_CONFIG_H
15#include <config.h>
16#endif
17
18#include "vcardstructuredimpl.h"
19#include "vcardstructured.h"
20#include "vcardvalue.h"
21#include "icalerror_p.h"
22#include "icallimits.h"
23#include "icalmemory.h"
24
25#include <ctype.h>
26#include <stdlib.h>
27#include <string.h>
28
29static vcardstructuredtype *vcardstructured_alloc(size_t num_fields)
30{
31 struct vcardstructuredtype_impl *st;
32
33 st = icalmemory_new_buffer(sizeof(struct vcardstructuredtype_impl));
34 if (!st) {
36 return NULL;
37 }
38 memset(st, 0, sizeof(struct vcardstructuredtype_impl));
39
40 if (num_fields > 0) {
41 st->field = (vcardstrarray **)icalmemory_new_buffer(num_fields * sizeof(vcardstrarray *));
42 if (!st->field) {
45 return NULL;
46 }
47 memset((void *)st->field, 0, num_fields * sizeof(vcardstrarray *));
48 st->num_alloc = num_fields;
49 }
50
51 return st;
52}
53
54static void vcardstructured_free(vcardstructuredtype *st)
55{
56 for (size_t i = 0; i < st->num_fields; i++) {
57 if (st->field[i]) {
58 vcardstrarray_free(st->field[i]);
59 }
60 }
61 icalmemory_free_buffer((void *)st->field);
62 icalmemory_free_buffer((void *)st);
63}
64
66{
67 struct vcardstructuredtype_impl *st = vcardstructured_alloc(num_fields);
68 if (!st) {
69 return st;
70 }
72
73 st->num_fields = num_fields;
74 return st;
75}
76
78{
79 struct vcardstructuredtype_impl *st = vcardstructured_alloc(0);
80 if (!st) {
81 return st;
82 }
84
85 if (!*str) {
86 return st;
87 }
88
89 vcardstrarray *field = vcardstrarray_new(2);
90 vcardstructured_set_field_at(st, st->num_fields, field);
91
92 size_t cnt = 0;
93 const size_t max_chars = icallimit_get(ICAL_LIMIT_PARSE_SEARCH);
94 do {
95 char *dequoted_str = vcardvalue_strdup_and_dequote_text(&str, ",;");
96
97 if (*str == ',' || field->num_elements || strlen(dequoted_str)) {
98 vcardstrarray_append(field, dequoted_str);
99 }
100 icalmemory_free_buffer(dequoted_str);
101
102 if (*str == ';') {
103 /* end of field */
104 field = vcardstrarray_new(2);
105 vcardstructured_set_field_at(st, st->num_fields, field);
106 }
107
108 } while (*str++ != '\0' && cnt++ < max_chars);
109
110 return st;
111}
112
114{
115 icalerror_check_arg_rv((st != NULL), "st");
116
117 st->refcount++;
118}
119
121{
122 icalerror_check_arg_rv((st != NULL), "st");
123 icalerror_check_arg_rv((st->refcount > 0), "st->refcount > 0");
124
125 st->refcount--;
126
127 if (st->refcount != 0) {
128 return;
129 }
130
131 vcardstructured_free(st);
132}
133
135{
136 icalerror_check_arg_rz((st != NULL), "st");
137
138 struct vcardstructuredtype_impl *clone_st = vcardstructured_alloc(st->num_fields);
139 if (!clone_st) {
140 return NULL;
141 }
142 vcardstructured_ref(clone_st);
143
144 clone_st->num_fields = st->num_fields;
145 for (size_t i = 0; i < st->num_fields; i++) {
146 clone_st->field[i] = vcardstrarray_clone(st->field[i]);
147 }
148
149 return clone_st;
150}
151
153{
154 icalerror_check_arg_rz((st != NULL), "st");
155 return st->num_fields;
156}
157
159 size_t num_fields)
160{
161 icalerror_check_arg_rv((st != NULL), "st");
162
163 if (num_fields > st->num_alloc) {
164 size_t new_alloc = ((num_fields + 7) / 8) * 8;
165 vcardstrarray **new_field = (vcardstrarray **)icalmemory_new_buffer(new_alloc * sizeof(vcardstrarray *));
166 if (!new_field) {
168 return;
169 }
170
171 if (st->num_fields && st->field) {
172 memcpy((void *)new_field, (void *)st->field, st->num_fields * sizeof(vcardstrarray *));
173 }
174 memset((void *)(new_field + st->num_alloc), 0,
175 (new_alloc - st->num_alloc) * sizeof(vcardstrarray *));
176
177 icalmemory_free_buffer((void *)st->field);
178 st->field = new_field;
179 st->num_alloc = new_alloc;
180 }
181
182 for (size_t i = num_fields; i < st->num_fields; i++) {
183 vcardstrarray_free(st->field[i]);
184 st->field[i] = NULL;
185 }
186
187 st->num_fields = num_fields;
188}
189
191 size_t position)
192{
193 icalerror_check_arg_rz((st != NULL), "st");
194 icalerror_check_arg_rz((st->num_fields > position), "position");
195
196 return st->field[position];
197}
198
200 size_t position,
201 vcardstrarray *field)
202{
203 icalerror_check_arg_rv((st != NULL), "st");
204
205 if (position >= st->num_fields) {
206 vcardstructured_set_num_fields(st, position + 1);
208 return;
209 }
210 }
211
212 vcardstrarray_free(st->field[position]);
213 st->field[position] = field;
214}
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Definition icalerror.c:90
@ ICAL_NEWFAILED_ERROR
Definition icalerror.h:50
#define icalerrno
Access the current icalerrno value.
Definition icalerror.h:130
size_t icallimit_get(icallimits_kind kind)
Definition icallimits.c:29
Defines the interface for getting/setting internal library limits.
@ ICAL_LIMIT_PARSE_SEARCH
Definition icallimits.h:26
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition icalmemory.c:353
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
Definition icalmemory.c:313
Common memory management routines.
void vcardstructured_set_field_at(vcardstructuredtype *st, size_t position, vcardstrarray *field)
Sets the field at the given position in a vcardstructuredtype.
vcardstrarray * vcardstructured_field_at(const vcardstructuredtype *st, size_t position)
Returns the field at the given position in a vcardstructuredtype.
void vcardstructured_ref(vcardstructuredtype *st)
Increments the reference count of the vcardstructuredtype.
vcardstructuredtype * vcardstructured_new_from_string(const char *str)
Creates a new instance of vcardstructuredtype from a string.
void vcardstructured_set_num_fields(vcardstructuredtype *st, size_t num_fields)
Sets the number of fields in a vcardstructuredtype.
vcardstructuredtype * vcardstructured_clone(const vcardstructuredtype *st)
Clones a vcardstructuredtype.
void vcardstructured_unref(vcardstructuredtype *st)
Decrements the reference count of the vcardstructuredtype.
size_t vcardstructured_num_fields(const vcardstructuredtype *st)
Returns the number of fields in a vcardstructuredtype.
vcardstructuredtype * vcardstructured_new(size_t num_fields)
Creates a new instance of vcardstructuredtype.
Defines the data structure representing vCard structured values.
struct vcardstructuredtype_impl vcardstructuredtype
Represents a decoded, structured text value.
Defines the data structure representing vCard values.