Line data Source code
1 : #include "mem.h"
2 : #include <string.h>
3 :
4 8 : Return memory_copy_literal(
5 : memory *destination,
6 : const char *literal)
7 : {
8 : /** Return status
9 : * The status that will be passed to return() before exiting
10 : * By default, the function worked without errors
11 : */
12 8 : Return status = SUCCESS;
13 :
14 8 : if(destination == NULL)
15 : {
16 0 : slog(ERROR,"Memory management; copy_literal destination must be non-NULL");
17 0 : status = FAILURE;
18 : }
19 :
20 8 : if(SUCCESS == status && literal == NULL)
21 : {
22 : /* Treat NULL literals as a no-op to keep existing payload intact */
23 0 : provide(SUCCESS);
24 : }
25 :
26 8 : if(SUCCESS == status && destination->element_size != sizeof(char))
27 : {
28 0 : slog(ERROR,"Memory management; copy_literal supports byte-sized elements only");
29 0 : status = FAILURE;
30 : }
31 :
32 8 : size_t literal_length = 0;
33 :
34 8 : if(SUCCESS == status)
35 : {
36 8 : literal_length = strlen(literal);
37 : }
38 :
39 8 : size_t new_total_elements = 0;
40 :
41 8 : if(SUCCESS == status)
42 : {
43 8 : if(literal_length == SIZE_MAX)
44 : {
45 0 : slog(ERROR,"Memory management; Not enough room for string terminator");
46 0 : status = FAILURE;
47 : } else {
48 8 : new_total_elements = literal_length + 1;
49 : }
50 : }
51 :
52 8 : size_t literal_bytes = 0;
53 :
54 8 : run(memory_guarded_size(destination->element_size,literal_length,&literal_bytes));
55 :
56 8 : run(resize(destination,new_total_elements));
57 :
58 8 : if(SUCCESS == status)
59 : {
60 8 : unsigned char *destination_bytes = (unsigned char *)destination->data;
61 :
62 8 : if(destination_bytes == NULL)
63 : {
64 0 : slog(ERROR,"Memory management; Destination data pointer is NULL after resize");
65 0 : status = FAILURE;
66 : } else {
67 8 : if(literal_bytes > 0)
68 : {
69 8 : memcpy(destination_bytes,literal,literal_bytes);
70 : }
71 :
72 8 : destination_bytes[literal_bytes] = '\0';
73 8 : telemetry_string_padding_event();
74 : }
75 : }
76 :
77 8 : provide(status);
78 : }
|