Line data Source code
1 : #include "mem.h"
2 : #include <string.h>
3 :
4 0 : Return memory_append(
5 : memory *destination,
6 : const memory *source)
7 : {
8 0 : Return status = SUCCESS;
9 :
10 0 : if(destination == NULL || source == NULL)
11 : {
12 0 : slog(ERROR,"Memory management; append arguments must be non-NULL");
13 0 : provide(FAILURE);
14 : }
15 :
16 0 : if(destination->element_size == 0)
17 : {
18 0 : slog(ERROR,"Memory management; Destination element size is zero (uninitialized)");
19 0 : provide(FAILURE);
20 : }
21 :
22 0 : if(source->element_size == 0)
23 : {
24 0 : slog(ERROR,"Memory management; Source element size is zero (uninitialized)");
25 0 : provide(FAILURE);
26 : }
27 :
28 0 : if(destination->element_size != source->element_size)
29 : {
30 0 : slog(ERROR,
31 : "Memory management; Element size mismatch (%zu vs %zu)",
32 : destination->element_size,
33 : source->element_size);
34 0 : provide(FAILURE);
35 : }
36 :
37 0 : const size_t append_elements = source->length;
38 :
39 0 : if(append_elements == 0)
40 : {
41 0 : provide(status);
42 : }
43 :
44 0 : const size_t original_elements = destination->length;
45 :
46 0 : if(append_elements > SIZE_MAX - original_elements)
47 : {
48 0 : slog(ERROR,"Memory management; Append would overflow element count");
49 0 : provide(FAILURE);
50 : }
51 :
52 0 : size_t append_bytes = 0;
53 :
54 0 : run(memory_guarded_size(source->element_size,append_elements,&append_bytes));
55 :
56 0 : if(FAILURE == status)
57 : {
58 0 : slog(ERROR,"Memory management; Overflow computing append bytes");
59 : }
60 :
61 0 : size_t offset_bytes = 0;
62 :
63 0 : run(memory_guarded_size(destination->element_size,original_elements,&offset_bytes));
64 :
65 0 : if(FAILURE == status)
66 : {
67 0 : slog(ERROR,"Memory management; Overflow computing append offset");
68 : }
69 :
70 0 : const size_t new_total_elements = original_elements + append_elements;
71 :
72 0 : if(SUCCESS == status)
73 : {
74 0 : run(resize(destination,new_total_elements));
75 : }
76 :
77 0 : if(SUCCESS == status)
78 : {
79 0 : unsigned char *destination_bytes = (unsigned char *)destination->data;
80 :
81 0 : if(destination_bytes == NULL || source->data == NULL)
82 : {
83 0 : slog(ERROR,"Memory management; Data pointer is NULL during append");
84 0 : status = FAILURE;
85 : } else {
86 0 : memcpy(destination_bytes + offset_bytes,source->data,append_bytes);
87 : }
88 : }
89 :
90 0 : provide(status);
91 : }
|