Branch data Line data Source code
1 : : #include "mem.h"
2 : : #include "mem_internal.h"
3 : :
4 : : /**
5 : : * @brief Return a writable typed pointer after verifying the element size
6 : : *
7 : : * This helper powers the public writable checked-access API. It verifies that
8 : : * the descriptor exists, that its element size is initialized, that the
9 : : * reserved byte count still describes a coherent buffer, and that the caller's
10 : : * expected element size matches the descriptor's actual element size.
11 : : *
12 : : * When all checks pass, the function returns the descriptor's writable storage
13 : : * pointer without changing string metadata or any other descriptor fields. When
14 : : * any invariant is broken, it reports the problem in a user-readable form and
15 : : * returns `NULL`
16 : : *
17 : : * @param memory_structure Pointer to a descriptor
18 : : * @param expected_single_element_size Expected element size in bytes, usually `sizeof(T)`
19 : : * @return Writable data pointer on success. `NULL` when the descriptor is invalid or the element size does not match
20 : : */
21 : 31975 : void *mem_data_writable(
22 : : memory *memory_structure,
23 : : size_t expected_single_element_size)
24 : : {
25 : 31975 : size_t current_payload_bytes = 0;
26 : :
27 [ + + ]: 31975 : if(memory_structure == NULL)
28 : : {
29 : 1 : report("Memory management; Descriptor is NULL");
30 : 1 : return(NULL);
31 : : }
32 : :
33 [ + + ]: 31974 : if(memory_structure->single_element_size == 0)
34 : : {
35 : 1 : report("Memory management; Descriptor element size is zero (uninitialized)");
36 : 1 : return(NULL);
37 : : }
38 : :
39 [ + + + + ]: 31973 : if(memory_structure->data == NULL && memory_structure->actually_allocated_bytes > 0)
40 : : {
41 : 1 : report("Memory management; Descriptor has reserved bytes with NULL data pointer");
42 : 1 : return(NULL);
43 : : }
44 : :
45 [ + - + + ]: 31972 : if(memory_structure->length > 0 && memory_structure->data == NULL)
46 : : {
47 : 1 : report("Memory management; Descriptor has non-zero length with NULL data pointer");
48 : 1 : return(NULL);
49 : : }
50 : :
51 : 31971 : Return guarded_status = mem_guarded_byte_size(
52 : : memory_structure,
53 : : memory_structure->length,
54 : : ¤t_payload_bytes);
55 : :
56 [ - + ]: 31971 : if((TRIUMPH & guarded_status) == 0)
57 : : {
58 : 0 : return(NULL);
59 : : }
60 : :
61 [ + - ]: 31971 : if(memory_structure->length > 0 &&
62 [ + + ]: 31971 : memory_structure->actually_allocated_bytes < current_payload_bytes)
63 : : {
64 : 1 : report("Memory management; Descriptor reserve is smaller than logical payload");
65 : 1 : return(NULL);
66 : : }
67 : :
68 [ + + ]: 31970 : if(memory_structure->single_element_size != expected_single_element_size)
69 : : {
70 : 2 : report("Memory management; Expected %zu bytes but descriptor uses %zu",expected_single_element_size,memory_structure->single_element_size);
71 : 2 : return(NULL);
72 : : }
73 : :
74 : 31968 : return(memory_structure->data);
75 : : }
|