Branch data Line data Source code
1 : : #include "mem_internal.h"
2 : :
3 : : /**
4 : : * @brief Find the first zero-valued element inside a descriptor
5 : : *
6 : : * A zero-valued element means that every byte in that element is zero. When no
7 : : * terminator is found within the current logical bounds, the function returns
8 : : * @ref memory::length through @p terminator_position_out. Descriptors that
9 : : * advertise a non-zero @ref memory::length with a `NULL`
10 : : * @ref memory::data pointer are rejected as inconsistent. The bounded scan is
11 : : * delegated to the shared raw string counter, which keeps the byte-sized
12 : : * `memchr` fast path and the wider element scan in one place
13 : : *
14 : : * The value written through @p terminator_position_out is guaranteed only
15 : : * when the function returns `SUCCESS`. On failure, the output object is left
16 : : * unspecified
17 : : *
18 : : * @param memory_structure Descriptor to scan
19 : : * @param terminator_position_out Output pointer for the first zero-valued
20 : : * element position. Its value is defined only on `SUCCESS`
21 : : * @return `SUCCESS` on success; `FAILURE` otherwise
22 : : */
23 : 21 : Return mem_find_zero_terminator(
24 : : const memory *memory_structure,
25 : : size_t *terminator_position_out)
26 : : {
27 : : /* This function was reviewed line by line by a human before this AI-assisted change.
28 : : This changed version requires a new separate human line-by-line review before it is considered trusted.
29 : : Any future change to this function requires separate explicit approval */
30 : :
31 : : /* Status returned by this function through provide()
32 : : Default value assumes successful completion */
33 : 21 : Return status = SUCCESS;
34 : :
35 [ + - - + ]: 21 : if(memory_structure == NULL || terminator_position_out == NULL)
36 : : {
37 : 0 : report("Memory management; Invalid arguments for zero terminator search");
38 : 0 : status = FAILURE;
39 [ - + ]: 21 : } else if(memory_structure->single_element_size == 0){
40 : 0 : report("Memory management; Descriptor element size is zero (uninitialized)");
41 : 0 : status = FAILURE;
42 [ + - - + ]: 21 : } else if(memory_structure->length > 0 && memory_structure->data == NULL){
43 : 0 : report("Memory management; Descriptor has non-zero length with NULL data pointer");
44 : 0 : status = FAILURE;
45 : : }
46 : :
47 [ + - - + ]: 21 : if((TRIUMPH & status) && memory_structure->length == 0)
48 : : {
49 : 0 : *terminator_position_out = 0;
50 : : }
51 : :
52 [ + - + - ]: 21 : if((TRIUMPH & status) && memory_structure->length > 0)
53 : : {
54 : : /* Read-only byte view over the descriptor payload used for bounded element scans */
55 : 21 : const unsigned char *memory_structure_data_view = (const unsigned char *)memory_structure->data;
56 : :
57 : : /* Total descriptor payload size in bytes used to guard the scan bounds */
58 : 21 : size_t descriptor_size_in_bytes = 0;
59 : :
60 : 21 : run(mem_guarded_byte_size(memory_structure,memory_structure->length,&descriptor_size_in_bytes));
61 : :
62 [ - + ]: 21 : if(CRITICAL & status)
63 : : {
64 : 0 : report("Memory management; Zero terminator search range overflows for %zu elements of size %zu",
65 : : memory_structure->length,
66 : : memory_structure->single_element_size);
67 : : }
68 : :
69 [ + - ]: 21 : if(TRIUMPH & status)
70 : : {
71 : 21 : run(mem_string_measure_length(
72 : : memory_structure_data_view,
73 : : descriptor_size_in_bytes,
74 : : memory_structure->single_element_size,
75 : : true,
76 : : terminator_position_out,
77 : : NULL));
78 : : }
79 : : }
80 : :
81 : 21 : provide(status);
82 : : }
|