Coverage Report

Created: 2025-07-23 07:11

/src/vlc/src/misc/ancillary.c
Line
Count
Source (jump to first uncovered line)
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
791
{
44
791
    struct vlc_ancillary *ancillary = malloc(sizeof(*ancillary));
45
46
791
    if (ancillary == NULL)
47
0
        return NULL;
48
49
791
    vlc_atomic_rc_init(&ancillary->rc);
50
791
    ancillary->id = id;
51
791
    ancillary->data = data;
52
791
    ancillary->free_cb = free_cb;
53
54
791
    return ancillary;
55
791
}
56
57
void
58
vlc_ancillary_Release(struct vlc_ancillary *ancillary)
59
791
{
60
791
    if (vlc_atomic_rc_dec(&ancillary->rc))
61
0
    {
62
0
        if (ancillary->free_cb != NULL)
63
0
            ancillary->free_cb(ancillary->data);
64
0
        free(ancillary);
65
0
    }
66
791
}
67
68
struct vlc_ancillary *
69
vlc_ancillary_Hold(struct vlc_ancillary *ancillary)
70
791
{
71
791
    vlc_atomic_rc_inc(&ancillary->rc);
72
791
    return ancillary;
73
791
}
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
113M
{
84
113M
    struct vlc_ancillary *ancillary;
85
113M
    vlc_vector_foreach(ancillary, array)
86
791
        vlc_ancillary_Release(ancillary);
87
113M
    vlc_vector_clear(array);
88
113M
}
89
90
int
91
vlc_ancillary_array_Merge(vlc_ancillary_array *dst_array,
92
                          const vlc_ancillary_array *src_array)
93
12.7M
{
94
12.7M
    if (src_array->size == 0)
95
12.7M
        return VLC_SUCCESS;
96
97
0
    int ret = VLC_SUCCESS;
98
0
    for (size_t i = 0; i < src_array->size && ret == VLC_SUCCESS; ++i)
99
0
        ret = vlc_ancillary_array_Insert(dst_array, src_array->data[i]);
100
101
0
    return VLC_SUCCESS;
102
12.7M
}
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
791
{
125
791
    assert(ancillary != NULL);
126
127
791
    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
791
    bool success = vlc_vector_push(array, ancillary);
139
791
    if (!success)
140
0
        return VLC_ENOMEM;
141
791
    vlc_ancillary_Hold(ancillary);
142
143
791
    return VLC_SUCCESS;
144
791
}
145
146
struct vlc_ancillary *
147
vlc_ancillary_array_Get(const vlc_ancillary_array *array,
148
                        vlc_ancillary_id id)
149
691
{
150
691
    struct vlc_ancillary *ancillary_it;
151
691
    vlc_vector_foreach(ancillary_it, array)
152
0
    {
153
0
        if (ancillary_it->id == id)
154
0
            return ancillary_it;
155
0
    }
156
691
    return NULL;
157
691
}