GCC Code Coverage Report


Directory: src/gate/
File: src/gate/cxx_utilities.cpp
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 120 137 87.6%
Functions: 19 19 100.0%
Branches: 82 159 51.6%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/utilities.hpp"
30 #include "gate/utilities.h"
31 #include <exception>
32
33 namespace gate
34 {
35
36 template class GATE_CORE_CPP_API Array<String>;
37 template class GATE_CORE_CPP_API ArrayList<String>;
38 template class GATE_CORE_CPP_API Set<String>;
39 template class GATE_CORE_CPP_API Map<String, String>;
40
41
42 namespace util
43 {
44 8 String printByteSize(uint64_t bytes)
45 {
46 char buffer[256];
47
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 size_t used = gate_util_print_byte_size(bytes, buffer, sizeof(buffer) - 16);
48
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 return String(buffer, used);
49 }
50 2 char const* printResult(result_t resultCode)
51 {
52 2 return gate_result_text(resultCode);
53 }
54
55
56 2 String printException(Throwable const& xcpt, bool_t addResultCode, bool_t addErrorCode)
57 {
58
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 StringBuilder builder;
59 2 char const* msg = xcpt.getMessage();
60
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 size_t msg_len = gate_str_length(msg);
61
62
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (msg_len > 0)
63 {
64
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 builder.append(msg);
65 }
66 else
67 {
68 addResultCode = true;
69 }
70
71
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (addResultCode)
72 {
73 2 result_t resultCode = xcpt.getResult();
74
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (GATE_FAILED(resultCode))
75 {
76
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (builder.length() != 0)
77 {
78
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 builder.appendNewLine();
79 }
80
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 builder.append("Result code #");
81
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 builder.appendHex(gate_uint16_t(resultCode));
82
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 builder.append(" ", 1);
83
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
2 builder.append(printResult(resultCode));
84 }
85 }
86
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (addErrorCode)
87 {
88 2 uint32_t errorCode = static_cast<uint32_t>(xcpt.getErrorCode());
89
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (errorCode != 0)
90 {
91
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (builder.length() != 0)
92 {
93
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 builder.appendNewLine();
94 }
95
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 builder.append("Error code 0x");
96
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 builder.appendHex(errorCode);
97 }
98 }
99
100
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return builder.toString();
101 }
102
103 4 String printCurrentException(bool_t addResultCode, bool_t addErrorCode)
104 {
105
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
4 static StaticString const msgUnknownException = "Unknown Exception";
106
107 try
108 {
109 #if __cplusplus >= 201103L
110 8 std::exception_ptr xcpt_ptr = std::current_exception();
111
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 if (xcpt_ptr)
112 8 std::rethrow_exception(xcpt_ptr);
113 #else
114 // pre C++11 cannot check if exceptions are raised,
115 // std::terminate() is called, if this function if called from outside a catch-block
116 throw;
117 #endif
118 }
119 2 catch (Throwable const& throwable)
120 {
121
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 return printException(throwable, addResultCode, addErrorCode);
122 }
123 2 catch (std::exception const& xcpt)
124 {
125
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return String(xcpt.what());
126 }
127 2 catch (int num)
128 {
129
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 StringBuilder builder;
130
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 builder << "Numeric exception code #" << static_cast<int32_t>(num);
131
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 return builder.toString();
132 }
133 2 catch (...)
134 {
135 1 return msgUnknownException;
136 }
137 return String(); // no exception was thrown
138 }
139
140
141 4 String printDuration(uint64_t seconds, bool_t shortFormat)
142 {
143 char buffer[1024];
144
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 size_t buffer_used = gate_util_print_duration(seconds, buffer, sizeof(buffer), shortFormat);
145
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 return String(buffer, buffer_used);
146 }
147
148 1 ArrayList<String> convertStringArray(gate_array_t const& arr)
149 {
150 1 size_t len = gate_array_length(&arr);
151 1 ArrayList<String> ret(len);
152
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (size_t ndx = 0; ndx != len; ++ndx)
153 {
154
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 gate_string_t const* ptr = (gate_string_t const*)gate_array_get(&arr, ndx);
155
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (ptr)
156 {
157
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 ret.add(String::duplicate(*ptr));
158 }
159 }
160 1 return ret;
161 }
162
163 6 ArrayList<String> convertStringArray(gate_arraylist_t const& arr)
164 {
165 6 size_t len = gate_arraylist_length(arr);
166 6 ArrayList<String> ret(len);
167
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
17 for (size_t ndx = 0; ndx != len; ++ndx)
168 {
169
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 gate_string_t const* ptr = (gate_string_t const*)gate_arraylist_get(arr, ndx);
170
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (ptr)
171 {
172
1/2
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
11 ret.add(String::duplicate(*ptr));
173 }
174 }
175 6 return ret;
176 }
177
178 1 ArrayList<String> createStringArray(gate_array_t& arr)
179 {
180 1 ArrayList<String> ret;
181 try
182 {
183
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ret = convertStringArray(arr);
184
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_array_release(&arr);
185 }
186 catch (...)
187 {
188 gate_array_release(&arr);
189 throw;
190 }
191 1 return ret;
192 }
193
194 2 ArrayList<String> createStringArray(gate_arraylist_t& arr)
195 {
196 2 ArrayList<String> ret;
197 try
198 {
199
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ret = convertStringArray(arr);
200
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 gate_arraylist_release(arr);
201 2 arr = NULL;
202 }
203 catch (...)
204 {
205 gate_arraylist_release(arr);
206 arr = NULL;
207 throw;
208 }
209 2 return ret;
210 }
211
212 1 ArrayList<String> splitString(String const& text, String const& separator, size_t maxCount)
213 {
214
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 gate_arraylist_t arr = gate_util_string_split(text.c_impl(), separator.c_impl(), maxCount);
215
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!arr)
216 {
217 GATEXX_RAISE_ERROR(results::OutOfMemory);
218 }
219
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return createStringArray(arr);
220 }
221
222
223
224 1 gate_arraylist_t convertStringArray(Array<String> const& arr)
225 {
226 1 gate_arraylist_t lst = gate_util_stringarray_create();
227
228
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (lst != NULL)
229 {
230
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 for (Array<String>::const_iterator it(arr.begin()), itend(arr.end()); it != itend; ++it)
231 {
232 2 gate_string_t const* ptr = it->c_impl();
233
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (NULL == gate_arraylist_add(lst, ptr))
234 {
235 gate_arraylist_release(lst);
236 lst = NULL;
237 break;
238 }
239 }
240 }
241 1 return lst;
242 }
243
244 1 gate_arraylist_t convertStringArray(ArrayList<String> const& arr)
245 {
246 1 gate_arraylist_t lst = gate_util_stringarray_create();
247
248
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (lst != NULL)
249 {
250
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
3 for (ArrayList<String>::const_iterator it(arr.begin()), itend(arr.end()); it != itend; ++it)
251 {
252 2 gate_string_t const* ptr = it->c_impl();
253
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (NULL == gate_arraylist_add(lst, ptr))
254 {
255 gate_arraylist_release(lst);
256 lst = NULL;
257 break;
258 }
259 }
260 }
261 1 return lst;
262 }
263
264 9 size_t convertStringArray(Array<String> const& arr, gate_string_t* strarr, gate_size_t strarr_max)
265 {
266 9 size_t count = 0;
267
3/4
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
32 for (ArrayList<String>::const_iterator it(arr.begin()), itend(arr.end()); (it != itend) && (strarr_max != 0); ++it)
268 {
269 23 gate_string_t const* ptr = it->c_impl();
270 23 gate_string_duplicate(strarr, ptr);
271 23 ++count;
272 23 ++strarr;
273 23 --strarr_max;
274 }
275 9 return count;
276 }
277
278 8 void releaseStringArray(gate_string_t* strarr, gate_size_t strarrlength)
279 {
280
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 while (strarrlength-- > 0)
281 {
282 2 gate_string_release(strarr);
283 2 ++strarr;
284 }
285 6 }
286
287 15 VoidResult dumpType(type_id_t type, void const* data, Stream& stream)
288 {
289
1/2
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
15 result_t const result = gate_util_dump_type(stream.c_impl(), type, data);
290
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
30 return makeResult(result);
291 }
292
293 1 VoidResult dumpStruct(gate_struct_t const* ptrStruct, Stream& stream)
294 {
295
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 result_t const result = gate_util_dump_struct(stream.c_impl(), ptrStruct);
296
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return makeResult(result);
297 }
298
299 1 VoidResult setState(AtomicInt& state, int32_t value)
300 {
301
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 return makeResult(gate_util_state_set(state.c_impl(), value));
302 }
303
304 1 VoidResult updateState(AtomicInt& state, int32_t from_value, int32_t to_value)
305 {
306
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 return makeResult(gate_util_state_update(state.c_impl(), from_value, to_value));
307 }
308
309 4 Result<bool_t> awaitState(AtomicInt& state, int32_t await_value, uint32_t timeout_ms)
310 {
311
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 result_t result = gate_util_state_await(state.c_impl(), await_value, timeout_ms);
312
2/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 switch(result)
313 {
314
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 case results::Ok: return makeOk(true);
315
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 case results::Timeout: return makeOk(false);
316 default: return makeErr(result);
317 }
318 }
319
320 } // end of namespace util;
321
322 } // end of namespace gate
323