Coverage Report

Created: 2026-05-16 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/src/misc/ancillary.c
Line
Count
Source
1
/*****************************************************************************
2
 * ancillary.c: ancillary management functions
3
 *****************************************************************************
4
 * Copyright (C) 2021 VLC authors and VideoLAN
5
 *
6
 * This program is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19
 *****************************************************************************/
20
21
#ifdef HAVE_CONFIG_H
22
# include "config.h"
23
#endif
24
25
#include <vlc_common.h>
26
#include <vlc_atomic.h>
27
28
#include <vlc_ancillary.h>
29
30
struct vlc_ancillary
31
{
32
    vlc_atomic_rc_t rc;
33
34
    vlc_ancillary_id id;
35
    void *data;
36
    vlc_ancillary_free_cb free_cb;
37
};
38
39
struct vlc_ancillary *
40
vlc_ancillary_CreateWithFreeCb(void *data,
41
                               vlc_ancillary_id id,
42
                               vlc_ancillary_free_cb free_cb)
43
981
{
44
981
    struct vlc_ancillary *ancillary = malloc(sizeof(*ancillary));
45
46
981
    if (ancillary == NULL)
47
0
        return NULL;
48
49
981
    vlc_atomic_rc_init(&ancillary->rc);
50
981
    ancillary->id = id;
51
981
    ancillary->data = data;
52
981
    ancillary->free_cb = free_cb;
53
54
981
    return ancillary;
55
981
}
56
57
void
58
vlc_ancillary_Release(struct vlc_ancillary *ancillary)
59
1.58k
{
60
1.58k
    if (vlc_atomic_rc_dec(&ancillary->rc))
61
3
    {
62
3
        if (ancillary->free_cb != NULL)
63
3
            ancillary->free_cb(ancillary->data);
64
3
        free(ancillary);
65
3
    }
66
1.58k
}
67
68
struct vlc_ancillary *
69
vlc_ancillary_Hold(struct vlc_ancillary *ancillary)
70
1.58k
{
71
1.58k
    vlc_atomic_rc_inc(&ancillary->rc);
72
1.58k
    return ancillary;
73
1.58k
}
74
75
void *
76
vlc_ancillary_GetData(const struct vlc_ancillary *ancillary)
77
0
{
78
0
    return ancillary->data;
79
0
}
80
81
void
82
vlc_ancillary_array_Clear(vlc_ancillary_array *array)
83
336M
{
84
336M
    struct vlc_ancillary *ancillary;
85
336M
    vlc_vector_foreach(ancillary, array)
86
1.58k
        vlc_ancillary_Release(ancillary);
87
336M
    vlc_vector_clear(array);
88
336M
}
89
90
int
91
vlc_ancillary_array_Merge(vlc_ancillary_array *dst_array,
92
                          const vlc_ancillary_array *src_array)
93
22.4M
{
94
22.4M
    if (src_array->size == 0)
95
22.4M
        return VLC_SUCCESS;
96
97
300
    int ret = VLC_SUCCESS;
98
600
    for (size_t i = 0; i < src_array->size && ret == VLC_SUCCESS; ++i)
99
300
        ret = vlc_ancillary_array_Insert(dst_array, src_array->data[i]);
100
101
300
    return VLC_SUCCESS;
102
22.4M
}
103
104
int
105
vlc_ancillary_array_MergeAndClear(vlc_ancillary_array *dst_array,
106
                                  vlc_ancillary_array *src_array)
107
0
{
108
0
    if (dst_array->size == 0)
109
0
    {
110
0
        *dst_array = *src_array;
111
0
        vlc_ancillary_array_Init(src_array);
112
0
        return VLC_SUCCESS;
113
0
    }
114
115
0
    int ret = vlc_ancillary_array_Merge(dst_array, src_array);
116
0
    if (ret == VLC_SUCCESS)
117
0
        vlc_ancillary_array_Clear(src_array);
118
0
    return ret;
119
0
}
120
121
int
122
vlc_ancillary_array_Insert(vlc_ancillary_array *array,
123
                           struct vlc_ancillary *ancillary)
124
1.58k
{
125
1.58k
    assert(ancillary != NULL);
126
127
1.58k
    for (size_t i = 0; i < array->size; ++i)
128
0
    {
129
0
        struct vlc_ancillary *ancillary_it = array->data[i];
130
0
        if (ancillary_it->id == ancillary->id)
131
0
        {
132
0
            vlc_ancillary_Release(ancillary_it);
133
0
            array->data[i] = vlc_ancillary_Hold(ancillary);
134
0
            return VLC_SUCCESS;
135
0
        }
136
0
    }
137
138
1.58k
    bool success = vlc_vector_push(array, ancillary);
139
1.58k
    if (!success)
140
0
        return VLC_ENOMEM;
141
1.58k
    vlc_ancillary_Hold(ancillary);
142
143
1.58k
    return VLC_SUCCESS;
144
1.58k
}
145
146
struct vlc_ancillary *
147
vlc_ancillary_array_Get(const vlc_ancillary_array *array,
148
                        vlc_ancillary_id id)
149
31.7k
{
150
31.7k
    struct vlc_ancillary *ancillary_it;
151
31.7k
    vlc_vector_foreach(ancillary_it, array)
152
303
    {
153
303
        if (ancillary_it->id == id)
154
303
            return ancillary_it;
155
303
    }
156
31.4k
    return NULL;
157
31.7k
}