-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmessage.cc
More file actions
72 lines (57 loc) · 1.85 KB
/
Copy pathmessage.cc
File metadata and controls
72 lines (57 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "message.h"
#include <cassert>
#include <err.h>
#include <unistd.h>
void Message::Serialize(std::vector<uint8_t>* output) {
output->clear();
output->push_back(0);
output->push_back(0);
output->push_back(0);
output->push_back(0);
for (const auto& kv : *this) {
WriteSize(kv.first.length(), output);
output->insert(output->end(), kv.first.begin(), kv.first.end());
WriteSize(kv.second.length(), output);
output->insert(output->end(), kv.second.begin(), kv.second.end());
}
uint32_t total_size = static_cast<uint32_t>(output->size());
(*output)[0] = total_size >> 16;
(*output)[1] = total_size >> 24;
(*output)[2] = total_size >> 8;
(*output)[3] = total_size;
}
void Message::Send(int fd) {
std::vector<uint8_t> buffer;
Serialize(&buffer);
size_t offset = 0;
while (offset < buffer.size()) {
ssize_t ret = write(fd, &buffer[offset], buffer.size() - offset);
if (ret == -1) err(EXIT_FAILURE, "Writing to command socket failed");
offset += ret;
}
}
void Message::Deserialize(const std::vector<uint8_t>& input, size_t size) {
size_t i = 4;
while (i < size) {
size_t key_size = ReadSize(&i, input);
std::string key(reinterpret_cast<const char*>(&input[i]), key_size);
i += key_size;
size_t value_size = ReadSize(&i, input);
std::string value(reinterpret_cast<const char*>(&input[i]), value_size);
i += value_size;
(*this)[key] = value;
}
assert(i == size);
}
void Message::WriteSize(size_t size, std::vector<uint8_t>* output) {
if (size > 0x3fff) output->push_back(0x80 | (size >> 14));
if (size > 0x7f) output->push_back(0x80 | (size >> 7));
output->push_back(size & 0x7f);
}
size_t Message::ReadSize(size_t* i, const std::vector<uint8_t>& input) {
size_t result = 0;
do {
result = (result << 7) | input[*i];
} while (input[(*i)++] & 0x80);
return result;
}