1 /* vim: set expandtab ts=4 sw=4: */
2 /*
3  * You may redistribute this program and/or modify it under the terms of
4  * the GNU General Public License as published by the Free Software Foundation,
5  * either version 3 of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
14  */
15 #include "wire/Message.h"
16 #include "util/UniqueName.h"
17 
Message_new(uint32_t messageLength,uint32_t amountOfPadding,struct Allocator * alloc)18 struct Message* Message_new(uint32_t messageLength,
19                                           uint32_t amountOfPadding,
20                                           struct Allocator* alloc)
21 {
22     uint8_t* buff = Allocator_malloc(alloc, messageLength + amountOfPadding);
23     struct Message* out = Allocator_calloc(alloc, sizeof(struct Message), 1);
24     out->bytes = &buff[amountOfPadding];
25     out->length = out->capacity = messageLength;
26     out->padding = amountOfPadding;
27     out->alloc = alloc;
28     return out;
29 }
30 
Message_setAssociatedFd(struct Message * msg,int fd)31 void Message_setAssociatedFd(struct Message* msg, int fd)
32 {
33     if (fd == -1) {
34         msg->associatedFd = 0;
35     } else if (fd == 0) {
36         msg->associatedFd = -1;
37     } else {
38         msg->associatedFd = fd;
39     }
40 }
41 
Message_getAssociatedFd(struct Message * msg)42 int Message_getAssociatedFd(struct Message* msg)
43 {
44     if (msg->associatedFd == -1) {
45         return 0;
46     } else if (msg->associatedFd == 0) {
47         return -1;
48     } else {
49         return msg->associatedFd;
50     }
51 }
52 
Message_clone(struct Message * toClone,struct Allocator * alloc)53 struct Message* Message_clone(struct Message* toClone, struct Allocator* alloc)
54 {
55     Assert_true(toClone->capacity >= toClone->length);
56     int32_t len = toClone->capacity + toClone->padding;
57     uint8_t* allocation = Allocator_malloc(alloc, len + 8);
58     while (((uintptr_t)allocation % 8) != (((uintptr_t)toClone->bytes - toClone->padding) % 8)) {
59         allocation++;
60     }
61     Bits_memcpy(allocation, toClone->bytes - toClone->padding, len);
62     return Allocator_clone(alloc, (&(struct Message) {
63         .length = toClone->length,
64         .padding = toClone->padding,
65         .bytes = allocation + toClone->padding,
66         .capacity = toClone->capacity,
67         .alloc = alloc
68     }));
69 }
70 
Message_copyOver(struct Message * output,struct Message * input,struct Allocator * allocator)71 void Message_copyOver(struct Message* output,
72                                     struct Message* input,
73                                     struct Allocator* allocator)
74 {
75     size_t inTotalLength = input->length + input->padding;
76     size_t outTotalLength = output->length + output->padding;
77     uint8_t* allocation = output->bytes - output->padding;
78     if (inTotalLength > outTotalLength) {
79         allocation = Allocator_realloc(allocator, allocation, inTotalLength);
80     }
81     Bits_memcpy(allocation, input->bytes - input->padding, inTotalLength);
82     output->bytes = allocation + input->padding;
83     output->length = input->length;
84     output->padding = input->padding;
85 }