Coverage Report

Created: 2025-08-26 07:01

/src/dovecot/src/lib/array.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
2
3
#include "lib.h"
4
#include "array.h"
5
6
7
void *
8
array_idx_modifiable_i(const struct array *array, unsigned int idx)
9
1.87M
{
10
1.87M
  i_assert(idx < array->buffer->used / array->element_size);
11
1.87M
  return PTR_OFFSET(array->buffer->data, idx * array->element_size);
12
1.87M
}
13
14
void *array_idx_get_space_i(struct array *array, unsigned int idx)
15
1.38M
{
16
1.38M
  return buffer_get_space_unsafe(array->buffer, idx * array->element_size,
17
1.38M
               array->element_size);
18
1.38M
}
19
20
void array_idx_set_i(struct array *array, unsigned int idx, const void *data)
21
0
{
22
0
  buffer_write(array->buffer, idx * array->element_size,
23
0
         data, array->element_size);
24
0
}
25
26
void array_idx_clear_i(struct array *array, unsigned int idx)
27
123k
{
28
123k
  buffer_write_zero(array->buffer, idx * array->element_size,
29
123k
        array->element_size);
30
123k
}
31
32
void *array_insert_space_i(struct array *array, unsigned int idx)
33
0
{
34
0
  void *data;
35
0
  size_t pos;
36
37
0
  pos = idx * array->element_size;
38
0
  buffer_copy(array->buffer, pos + array->element_size,
39
0
        array->buffer, pos, SIZE_MAX);
40
41
0
  data = buffer_get_space_unsafe(array->buffer, pos, array->element_size);
42
0
  memset(data, 0, array->element_size);
43
0
  return data;
44
0
}
45
46
bool array_cmp_i(const struct array *array1, const struct array *array2)
47
0
{
48
0
  if (!array_is_created_i(array1) || array1->buffer->used == 0)
49
0
    return !array_is_created_i(array2) || array2->buffer->used == 0;
50
51
0
  if (!array_is_created_i(array2))
52
0
    return FALSE;
53
54
0
  return buffer_cmp(array1->buffer, array2->buffer);
55
0
}
56
57
bool array_equal_fn_i(const struct array *array1, const struct array *array2,
58
          int (*cmp)(const void *, const void*))
59
0
{
60
0
  unsigned int count1, count2, i;
61
0
  size_t size;
62
63
0
  if (!array_is_created_i(array1) || array1->buffer->used == 0)
64
0
    return !array_is_created_i(array2) || array2->buffer->used == 0;
65
66
0
  if (!array_is_created_i(array2))
67
0
    return FALSE;
68
69
0
  count1 = array_count_i(array1); count2 = array_count_i(array2);
70
0
  if (count1 != count2)
71
0
    return FALSE;
72
73
0
  size = array1->element_size;
74
0
  i_assert(size == array2->element_size);
75
76
0
  for (i = 0; i < count1; i++) {
77
0
    if (cmp(CONST_PTR_OFFSET(array1->buffer->data, i * size),
78
0
      CONST_PTR_OFFSET(array2->buffer->data, i * size)) != 0)
79
0
      return FALSE;
80
0
  }
81
0
  return TRUE;
82
0
}
83
84
bool array_equal_fn_ctx_i(const struct array *array1, const struct array *array2,
85
        int (*cmp)(const void *, const void *, const void *),
86
        const void *context)
87
0
{
88
0
  unsigned int count1, count2, i;
89
0
  size_t size;
90
91
0
  if (!array_is_created_i(array1) || array1->buffer->used == 0)
92
0
    return !array_is_created_i(array2) || array2->buffer->used == 0;
93
94
0
  if (!array_is_created_i(array2))
95
0
    return FALSE;
96
97
0
  count1 = array_count_i(array1); count2 = array_count_i(array2);
98
0
  if (count1 != count2)
99
0
    return FALSE;
100
101
0
  size = array1->element_size;
102
0
  i_assert(size == array2->element_size);
103
104
0
  for (i = 0; i < count1; i++) {
105
0
    if (cmp(CONST_PTR_OFFSET(array1->buffer->data, i * size),
106
0
      CONST_PTR_OFFSET(array2->buffer->data, i * size), context) != 0)
107
0
      return FALSE;
108
0
  }
109
0
  return TRUE;
110
0
}
111
112
void array_reverse_i(struct array *array)
113
0
{
114
0
  const size_t element_size = array->element_size;
115
0
  unsigned int i, count = array_count_i(array);
116
0
  size_t size;
117
0
  void *data, *tmp;
118
119
0
  data = buffer_get_modifiable_data(array->buffer, &size);
120
0
  tmp = t_buffer_get(array->element_size);
121
0
  for (i = 0; i+1 < count; i++, count--) {
122
0
    memcpy(tmp, PTR_OFFSET(data, i * element_size), element_size);
123
0
    memcpy(PTR_OFFSET(data, i * element_size),
124
0
           PTR_OFFSET(data, (count-1) * element_size),
125
0
           element_size);
126
0
    memcpy(PTR_OFFSET(data, (count-1) * element_size), tmp,
127
0
           element_size);
128
0
  }
129
0
}
130
131
void array_sort_i(struct array *array, int (*cmp)(const void *, const void *))
132
18.1k
{
133
18.1k
  unsigned int count;
134
135
18.1k
  count = array_count_i(array);
136
18.1k
  if (count == 0)
137
0
    return;
138
18.1k
  qsort(buffer_get_modifiable_data(array->buffer, NULL),
139
18.1k
        count, array->element_size, cmp);
140
18.1k
}
141
142
const void *array_bsearch_i(const struct array *array, const void *key,
143
                int (*cmp)(const void *, const void *))
144
108k
{
145
108k
  unsigned int count;
146
147
108k
  count = array_count_i(array);
148
108k
  return bsearch(key, array->buffer->data,
149
108k
           count, array->element_size, cmp);
150
108k
}
151
152
const void *array_lsearch_i(const struct array *array, const void *key,
153
          int (*cmp)(const void *, const void *))
154
0
{
155
0
  const void * const data = array->buffer->data;
156
0
  const size_t s = array->element_size;
157
0
  unsigned int idx;
158
159
0
  for (idx = 0; idx < array_count_i(array); idx++) {
160
0
    if (cmp(key, CONST_PTR_OFFSET(data, idx * s)) == 0) {
161
0
      return PTR_OFFSET(data, idx * s);
162
0
    }
163
0
  }
164
165
0
  return NULL;
166
0
}
167
168
const void *array_lsearch_ptr_i(const struct array *array, const void *key)
169
6.47k
{
170
6.47k
  i_assert(array->element_size == sizeof(key));
171
6.47k
  const void *const *data = array->buffer->data;
172
6.47k
  unsigned int i, count = array_count_i(array);
173
174
6.47k
  for (i = 0; i < count; i++) {
175
0
    if (data[i] == key)
176
0
      return data[i];
177
0
  }
178
6.47k
  return NULL;
179
6.47k
}
180
181
bool array_lsearch_ptr_idx_i(const struct array *array, const void *key,
182
           unsigned int *idx_r)
183
30.8k
{
184
30.8k
  i_assert(array->element_size == sizeof(key));
185
30.8k
  const void *const *data = array->buffer->data;
186
30.8k
  unsigned int i, count = array_count_i(array);
187
188
30.8k
  for (i = 0; i < count; i++) {
189
30.8k
    if (data[i] == key) {
190
30.8k
      *idx_r = i;
191
30.8k
      return TRUE;
192
30.8k
    }
193
30.8k
  }
194
0
  return FALSE;
195
30.8k
}