Branch data Line data Source code
1 : : #include "mem.h"
2 : : #include <string.h>
3 : :
4 : : /**
5 : : * @brief Copy visible bytes from a bounded source string buffer.
6 : : *
7 : : * Visible source length is measured with @ref memory_string_length semantics
8 : : * over a temporary descriptor view created from the provided source range.
9 : : */
10 : 36 : Return memory_copy_cstring(
11 : : memory *destination,
12 : : const char *source_buffer,
13 : : size_t source_buffer_size)
14 : : {
15 : : /* Status returned by this function through provide()
16 : : Default value assumes successful completion */
17 : 36 : Return status = SUCCESS;
18 : 36 : create(char,source_view);
19 : 36 : size_t source_length = 0;
20 : 36 : size_t total_elements = 0;
21 : :
22 [ - + ]: 36 : if(destination == NULL)
23 : : {
24 : 0 : report("Memory management; copy_cstring destination must be non-NULL");
25 : 0 : status = FAILURE;
26 : : }
27 : :
28 [ + - - + ]: 36 : if((TRIUMPH & status) && destination->element_size != sizeof(char))
29 : : {
30 : 0 : report("Memory management; copy_cstring supports byte-sized elements only");
31 : 0 : status = FAILURE;
32 : : }
33 : :
34 [ + - - + : 36 : if((TRIUMPH & status) && source_buffer == NULL && source_buffer_size > 0)
- - ]
35 : : {
36 : 0 : report("Memory management; copy_cstring source is NULL while size is %zu",source_buffer_size);
37 : 0 : status = FAILURE;
38 : : }
39 : :
40 [ + - - + ]: 36 : run(copy_buffer(source_view,source_buffer,source_buffer_size));
41 [ + - - + ]: 36 : run(string_length(source_view,&source_length));
42 : :
43 [ + - ]: 36 : if(TRIUMPH & status)
44 : : {
45 [ - + ]: 36 : if(source_length == SIZE_MAX)
46 : : {
47 : 0 : report("Memory management; Not enough room for string terminator");
48 : 0 : status = FAILURE;
49 : : } else {
50 : 36 : total_elements = source_length + 1;
51 : : }
52 : : }
53 : :
54 [ + - - + ]: 36 : run(resize(destination,total_elements));
55 : :
56 [ + - ]: 36 : if(TRIUMPH & status)
57 : : {
58 : 36 : unsigned char *destination_bytes = (unsigned char *)destination->data;
59 : :
60 [ - + ]: 36 : if(destination_bytes == NULL)
61 : : {
62 : 0 : report("Memory management; Destination data pointer is NULL after resize");
63 : 0 : status = FAILURE;
64 : : } else {
65 [ + - ]: 36 : if(source_length > 0)
66 : : {
67 : 36 : memcpy(destination_bytes,source_buffer,source_length);
68 : : }
69 : :
70 : 36 : destination_bytes[source_length] = '\0';
71 : 36 : telemetry_string_padding_event();
72 : : }
73 : : }
74 : :
75 [ - + - + ]: 36 : call(del(source_view));
76 : :
77 : 36 : provide(status);
78 : : }
|