Coverage Report

Created: 2026-10-17 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/S2OPC/src/Common/helpers/sopc_tsafe_dict.c
Line
Count
Source
1
/*
2
 * Licensed to Systerel under one or more contributor license
3
 * agreements. See the NOTICE file distributed with this work
4
 * for additional information regarding copyright ownership.
5
 * Systerel licenses this file to you under the Apache
6
 * License, Version 2.0 (the "License"); you may not use this
7
 * file except in compliance with the License. You may obtain
8
 * a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
20
#include "sopc_tsafe_dict.h"
21
#include "sopc_assert.h"
22
#include "sopc_mem_alloc.h"
23
#include "sopc_mutexes.h"
24
25
struct _SOPC_TSafe_Dict
26
{
27
    SOPC_Mutex lock;
28
    SOPC_TSafe_Dict_KeyCopy_Fct* copy_func;
29
    SOPC_Dict* dict;
30
};
31
32
SOPC_TSafe_Dict* SOPC_TSafe_Dict_Create(uintptr_t empty_key,
33
                                        SOPC_Dict_KeyHash_Fct* key_hash,
34
                                        SOPC_Dict_KeyEqual_Fct* key_equal,
35
                                        SOPC_TSafe_Dict_KeyCopy_Fct* key_copy,
36
                                        SOPC_Dict_Free_Fct* key_free,
37
                                        SOPC_Dict_Free_Fct* value_free)
38
0
{
39
0
    SOPC_TSafe_Dict* safeDict = SOPC_Calloc(1, sizeof(SOPC_TSafe_Dict));
40
0
    if (NULL == safeDict)
41
0
    {
42
0
        return NULL;
43
0
    }
44
0
    SOPC_ReturnStatus status = SOPC_Mutex_Initialization(&safeDict->lock);
45
0
    if (SOPC_STATUS_OK == status)
46
0
    {
47
0
        safeDict->copy_func = key_copy;
48
49
0
        safeDict->dict = SOPC_Dict_Create(empty_key, key_hash, key_equal, key_free, value_free);
50
0
        if (NULL == safeDict->dict)
51
0
        {
52
0
            status = SOPC_STATUS_NOK;
53
0
        }
54
0
    }
55
0
    if (SOPC_STATUS_OK != status)
56
0
    {
57
0
        SOPC_TSafe_Dict_Delete(safeDict);
58
0
        safeDict = NULL;
59
0
    }
60
0
    return safeDict;
61
0
}
62
63
void SOPC_TSafe_Dict_Delete(SOPC_TSafe_Dict* d)
64
0
{
65
0
    if (NULL != d)
66
0
    {
67
0
        SOPC_Dict_Delete(d->dict);
68
0
        SOPC_Mutex_Clear(&d->lock);
69
0
        SOPC_Free(d);
70
0
    }
71
0
}
72
73
bool SOPC_TSafe_Dict_Reserve(SOPC_TSafe_Dict* d, size_t n_items)
74
0
{
75
0
    if (NULL == d)
76
0
    {
77
0
        return false;
78
0
    }
79
0
    SOPC_Mutex_Lock(&d->lock);
80
0
    bool res = SOPC_Dict_Reserve(d->dict, n_items);
81
0
    SOPC_Mutex_Unlock(&d->lock);
82
0
    return res;
83
0
}
84
85
void SOPC_TSafe_Dict_SetTombstoneKey(SOPC_TSafe_Dict* d, uintptr_t tombstone_key)
86
0
{
87
0
    SOPC_ASSERT(NULL != d);
88
0
    SOPC_Mutex_Lock(&d->lock);
89
0
    SOPC_Dict_SetTombstoneKey(d->dict, tombstone_key);
90
0
    SOPC_Mutex_Unlock(&d->lock);
91
0
}
92
93
bool SOPC_TSafe_Dict_Insert(SOPC_TSafe_Dict* d, uintptr_t key, uintptr_t value)
94
0
{
95
0
    if (NULL == d)
96
0
    {
97
0
        return false;
98
0
    }
99
0
    SOPC_Mutex_Lock(&d->lock);
100
0
    bool res = SOPC_Dict_Insert(d->dict, key, value);
101
0
    SOPC_Mutex_Unlock(&d->lock);
102
0
    return res;
103
0
}
104
105
uintptr_t SOPC_TSafe_Dict_GetAndLock(SOPC_TSafe_Dict* d, const uintptr_t key, bool* found)
106
0
{
107
0
    if (NULL == d)
108
0
    {
109
0
        return (uintptr_t) NULL;
110
0
    }
111
0
    SOPC_Mutex_Lock(&d->lock);
112
0
    uintptr_t result = SOPC_Dict_Get(d->dict, key, found);
113
0
    return result;
114
0
}
115
116
uintptr_t SOPC_TSafe_Dict_GetCopy(SOPC_TSafe_Dict* d, const uintptr_t key, bool* found)
117
0
{
118
0
    if (NULL == d || NULL == d->copy_func)
119
0
    {
120
0
        return (uintptr_t) NULL;
121
0
    }
122
0
    uintptr_t copy = (uintptr_t) NULL;
123
0
    SOPC_Mutex_Lock(&d->lock);
124
0
    uintptr_t result = SOPC_Dict_Get(d->dict, key, found);
125
0
    if ((uintptr_t) NULL != result)
126
0
    {
127
0
        copy = d->copy_func(result);
128
0
    }
129
0
    SOPC_Mutex_Unlock(&d->lock);
130
0
    return copy;
131
0
}
132
133
uintptr_t SOPC_TSafe_Dict_GetKeyAndLock(SOPC_TSafe_Dict* d, const uintptr_t key, bool* found)
134
0
{
135
0
    if (NULL == d)
136
0
    {
137
0
        return (uintptr_t) NULL;
138
0
    }
139
0
    SOPC_Mutex_Lock(&d->lock);
140
0
    uintptr_t result = SOPC_Dict_GetKey(d->dict, key, found);
141
0
    return result;
142
0
}
143
144
void SOPC_TSafe_Dict_Unlock(SOPC_TSafe_Dict* d)
145
0
{
146
0
    SOPC_ASSERT(NULL != d);
147
0
    SOPC_Mutex_Unlock(&d->lock);
148
0
}
149
150
void SOPC_TSafe_Dict_Remove(SOPC_TSafe_Dict* d, const uintptr_t key)
151
0
{
152
0
    SOPC_ASSERT(NULL != d);
153
0
    SOPC_Mutex_Lock(&d->lock);
154
0
    SOPC_Dict_Remove(d->dict, key);
155
0
    SOPC_Mutex_Unlock(&d->lock);
156
0
}
157
158
SOPC_Dict_Free_Fct* SOPC_TSafe_Dict_GetKeyFreeFunc(SOPC_TSafe_Dict* d)
159
0
{
160
0
    if (NULL == d)
161
0
    {
162
0
        return NULL;
163
0
    }
164
0
    SOPC_Mutex_Lock(&d->lock);
165
0
    SOPC_Dict_Free_Fct* freeFct = SOPC_Dict_GetKeyFreeFunc(d->dict);
166
0
    SOPC_Mutex_Unlock(&d->lock);
167
0
    return freeFct;
168
0
}
169
170
void SOPC_TSafe_Dict_SetKeyFreeFunc(SOPC_TSafe_Dict* d, SOPC_Dict_Free_Fct* func)
171
0
{
172
0
    SOPC_ASSERT(NULL != d);
173
0
    SOPC_Mutex_Lock(&d->lock);
174
0
    SOPC_Dict_SetKeyFreeFunc(d->dict, func);
175
0
    SOPC_Mutex_Unlock(&d->lock);
176
0
}
177
178
SOPC_Dict_Free_Fct* SOPC_TSafe_Dict_GetValueFreeFunc(SOPC_TSafe_Dict* d)
179
0
{
180
0
    if (NULL == d)
181
0
    {
182
0
        return NULL;
183
0
    }
184
0
    SOPC_Mutex_Lock(&d->lock);
185
0
    SOPC_Dict_Free_Fct* func = SOPC_Dict_GetValueFreeFunc(d->dict);
186
0
    SOPC_Mutex_Unlock(&d->lock);
187
0
    return func;
188
0
}
189
190
void SOPC_TSafe_Dict_SetValueFreeFunc(SOPC_TSafe_Dict* d, SOPC_Dict_Free_Fct* func)
191
0
{
192
0
    SOPC_ASSERT(NULL != d);
193
0
    SOPC_Mutex_Lock(&d->lock);
194
0
    SOPC_Dict_SetValueFreeFunc(d->dict, func);
195
0
    SOPC_Mutex_Unlock(&d->lock);
196
0
}
197
198
size_t SOPC_TSafe_Dict_Size(SOPC_TSafe_Dict* d)
199
0
{
200
0
    if (NULL == d)
201
0
    {
202
0
        return 0;
203
0
    }
204
0
    SOPC_Mutex_Lock(&d->lock);
205
0
    size_t s = SOPC_Dict_Size(d->dict);
206
0
    SOPC_Mutex_Unlock(&d->lock);
207
0
    return s;
208
0
}
209
210
size_t SOPC_TSafe_Dict_Capacity(SOPC_TSafe_Dict* d)
211
0
{
212
0
    if (NULL == d)
213
0
    {
214
0
        return 0;
215
0
    }
216
0
    SOPC_Mutex_Lock(&d->lock);
217
0
    size_t s = SOPC_Dict_Capacity(d->dict);
218
0
    SOPC_Mutex_Unlock(&d->lock);
219
0
    return s;
220
0
}
221
222
void SOPC_TSafe_Dict_ForEach(SOPC_TSafe_Dict* d, SOPC_Dict_ForEach_Fct* func, uintptr_t user_data)
223
0
{
224
0
    SOPC_ASSERT(NULL != d);
225
0
    SOPC_Mutex_Lock(&d->lock);
226
0
    SOPC_Dict_ForEach(d->dict, func, user_data);
227
0
    SOPC_Mutex_Unlock(&d->lock);
228
0
}