Branch data Line data Source code
1 : : #include "mem.h"
2 : :
3 : : /**
4 : : * @brief Concatenate a raw byte buffer to a descriptor.
5 : : *
6 : : * Interprets @p source_buffer_size as the exact number of bytes to append.
7 : : * The destination is resized by `source_buffer_size / element_size` elements
8 : : * and receives a byte-for-byte payload copy.
9 : : *
10 : : * This helper performs binary concatenation only. It does not scan for
11 : : * `'\0'`, does not enforce string termination, and preserves embedded zero
12 : : * bytes exactly as provided.
13 : : */
14 : 0 : Return memory_concat_buffer(
15 : : memory *destination,
16 : : const void *source_buffer,
17 : : size_t source_buffer_size)
18 : : {
19 : : /* Status returned by this function through provide()
20 : : Default value assumes successful completion */
21 : 0 : Return status = SUCCESS;
22 : :
23 [ # # ]: 0 : if(destination == NULL)
24 : : {
25 : 0 : report("Memory management; concat_buffer destination must be non-NULL");
26 : 0 : provide(FAILURE);
27 : : }
28 : :
29 [ # # ]: 0 : if(destination->element_size == 0)
30 : : {
31 : 0 : report("Memory management; Destination element size is zero (uninitialized)");
32 : 0 : provide(FAILURE);
33 : : }
34 : :
35 [ # # ]: 0 : if(source_buffer == NULL)
36 : : {
37 [ # # ]: 0 : if(source_buffer_size == 0)
38 : : {
39 : 0 : provide(status);
40 : : }
41 : :
42 : 0 : report("Memory management; concat_buffer source is NULL while size is %zu",source_buffer_size);
43 : 0 : provide(FAILURE);
44 : : }
45 : :
46 [ # # ]: 0 : if((source_buffer_size % destination->element_size) != 0)
47 : : {
48 : 0 : report("Memory management; concat_buffer size %zu is not divisible by element size %zu",source_buffer_size,destination->element_size);
49 : 0 : provide(FAILURE);
50 : : }
51 : :
52 : 0 : size_t append_elements = 0;
53 : :
54 [ # # ]: 0 : if(TRIUMPH & status)
55 : : {
56 : 0 : append_elements = source_buffer_size / destination->element_size;
57 : : }
58 : :
59 [ # # ]: 0 : if(append_elements == 0)
60 : : {
61 : 0 : provide(status);
62 : : }
63 : :
64 [ # # ]: 0 : if(append_elements > SIZE_MAX - destination->length)
65 : : {
66 : 0 : report("Memory management; concat_buffer would overflow element count");
67 : 0 : provide(FAILURE);
68 : : }
69 : :
70 : 0 : size_t offset_bytes = 0;
71 : :
72 [ # # # # ]: 0 : run(memory_guarded_size(destination->element_size,destination->length,&offset_bytes));
73 : :
74 [ # # ]: 0 : if(CRITICAL & status)
75 : : {
76 : 0 : report("Memory management; Overflow computing concat_buffer destination offset");
77 : 0 : provide(status);
78 : : }
79 : :
80 [ # # # # ]: 0 : run(resize(destination,destination->length + append_elements));
81 : :
82 [ # # ]: 0 : if(TRIUMPH & status)
83 : : {
84 : 0 : unsigned char *destination_bytes = (unsigned char *)destination->data;
85 : :
86 [ # # ]: 0 : if(destination_bytes == NULL)
87 : : {
88 : 0 : report("Memory management; Destination data pointer is NULL during concat_buffer");
89 : 0 : status = FAILURE;
90 : : } else {
91 : 0 : memcpy(destination_bytes + offset_bytes,source_buffer,source_buffer_size);
92 : : }
93 : : }
94 : :
95 : 0 : provide(status);
96 : : }
|