Branch data Line data Source code
1 : : #include "mem.h"
2 : : #include "mem_internal.h"
3 : :
4 : : /**
5 : : * @brief Convert a descriptor from string mode to generic data mode
6 : : *
7 : : * Clears string metadata by setting @ref memory::string_length to `0` and
8 : : * @ref memory::is_string to `false`. The current implementation accepts
9 : : * byte-sized string elements only. If the descriptor currently represents a
10 : : * canonical string view whose logical length is exactly
11 : : * `string_length + 1` elements and whose last logical element is a zero-valued
12 : : * terminator element, that trailing element is treated as an explicit service
13 : : * marker for the end of the string rather than useful raw payload. The helper
14 : : * reduces @ref memory::length by one so only the string payload remains part
15 : : * of the logical descriptor. Descriptors that are already in data mode are
16 : : * accepted as a successful no-op. Descriptors that advertise non-zero length
17 : : * with a `NULL` data pointer are rejected as inconsistent
18 : : *
19 : : * @param memory_structure Descriptor that should from now on be treated as data
20 : : * @return `SUCCESS` on success; `FAILURE` otherwise
21 : : */
22 : 6 : Return mem_convert_string_to_data(memory *memory_structure)
23 : : {
24 : : /* Status returned by this function through provide()
25 : : Default value assumes successful completion */
26 : 6 : Return status = SUCCESS;
27 : :
28 [ - + ]: 6 : if(memory_structure == NULL)
29 : : {
30 : 0 : report("Memory management; Invalid arguments for data conversion");
31 : 0 : status = FAILURE;
32 : : }
33 : :
34 [ + - + - : 6 : if((TRIUMPH & status) && memory_structure->length > 0 && memory_structure->data == NULL)
+ + ]
35 : : {
36 : 1 : report("Memory management; Descriptor has non-zero length with NULL data pointer");
37 : 1 : status = FAILURE;
38 : : }
39 : :
40 [ + + + - ]: 6 : if((TRIUMPH & status) && memory_structure->is_string == true)
41 : : {
42 [ + + ]: 5 : if(memory_structure->single_element_size == 0)
43 : : {
44 : 1 : report("Memory management; Descriptor element size is zero (uninitialized)");
45 : 1 : status = FAILURE;
46 : : }
47 : :
48 [ + + - + ]: 5 : if((TRIUMPH & status) && memory_structure->single_element_size != sizeof(char))
49 : : {
50 : 0 : report("Memory management; String-to-data conversion supports byte-sized elements only");
51 : 0 : status = FAILURE;
52 : : }
53 : :
54 [ + + ]: 5 : if((TRIUMPH & status) &&
55 [ + - ]: 4 : memory_structure->length > 0 &&
56 [ + + ]: 4 : memory_structure->string_length == memory_structure->length - 1)
57 : : {
58 : 3 : const unsigned char *memory_structure_data_view = (const unsigned char *)memory_structure->data;
59 : :
60 [ - + ]: 3 : if(memory_structure_data_view == NULL)
61 : : {
62 : 0 : report("Memory management; Data pointer is NULL while converting string to data");
63 : 0 : status = FAILURE;
64 : : }
65 : :
66 [ + - ]: 3 : if(TRIUMPH & status)
67 : : {
68 : : /* Byte offset of the last logical element, which may be the trailing terminator */
69 : 3 : size_t terminator_offset = 0;
70 : :
71 : : /* Becomes true only when the last logical element is an all-zero terminator */
72 : 3 : bool trailing_terminator_is_zero = false;
73 : :
74 : 3 : run(mem_guarded_byte_size(memory_structure,memory_structure->length - 1,&terminator_offset));
75 : :
76 [ + - ]: 3 : if(TRIUMPH & status)
77 : : {
78 : 3 : trailing_terminator_is_zero = mem_is_zero_element(
79 : : memory_structure_data_view + terminator_offset,
80 : : memory_structure->single_element_size);
81 : : }
82 : :
83 [ + - + - ]: 3 : if((TRIUMPH & status) && trailing_terminator_is_zero == true)
84 : : {
85 : 3 : const size_t terminator_bytes = memory_structure->single_element_size;
86 : 3 : memory_structure->length--;
87 : 3 : telemetry_current_payload_bytes_removed(terminator_bytes);
88 : 3 : telemetry_block_overhead_bytes_added(terminator_bytes);
89 : : }
90 : : }
91 : : }
92 : : }
93 : :
94 [ + + ]: 6 : if(TRIUMPH & status)
95 : : {
96 [ + - ]: 4 : if(memory_structure->is_string == true)
97 : : {
98 : 4 : telemetry_string_to_data_conversions();
99 : : }
100 : :
101 : 4 : memory_structure->string_length = 0;
102 : 4 : memory_structure->is_string = false;
103 : : }
104 : :
105 : 6 : provide(status);
106 : : }
|