forked from pi-hole/FTL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
msgpack.c
118 lines (96 loc) · 3.28 KB
/
msgpack.c
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* MessagePack serialization
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
#include "api.h"
void pack_eom(int sock) {
// This byte is explicitly never used in the MessagePack spec, so it is perfect to use as an EOM for this API.
uint8_t eom = 0xc1;
swrite(sock, &eom, sizeof(eom));
}
void pack_basic(int sock, uint8_t format, void *value, size_t size) {
swrite(sock, &format, sizeof(format));
swrite(sock, value, size);
}
uint64_t leToBe64(uint64_t value) {
char *ptr = (char *) &value;
uint32_t part1, part2;
// Copy the two halves of the 64 bit input into uint32_t's so we can use htonl
memcpy(&part1, ptr, 4);
memcpy(&part2, ptr + 4, 4);
// Flip each half around
part1 = htonl(part1);
part2 = htonl(part2);
// Arrange them to form the big-endian version of the original input
return (uint64_t) part1 << 32 | part2;
}
void pack_bool(int sock, bool value) {
uint8_t packed = (uint8_t) (value ? 0xc3 : 0xc2);
swrite(sock, &packed, sizeof(packed));
}
void pack_uint8(int sock, uint8_t value) {
pack_basic(sock, 0xcc, &value, sizeof(value));
}
void pack_uint64(int sock, uint64_t value) {
uint64_t bigEValue = leToBe64(value);
pack_basic(sock, 0xcf, &bigEValue, sizeof(bigEValue));
}
void pack_int32(int sock, int32_t value) {
uint32_t bigEValue = htonl((uint32_t) value);
pack_basic(sock, 0xd2, &bigEValue, sizeof(bigEValue));
}
void pack_int64(int sock, int64_t value) {
// Need to use memcpy to do a direct copy without reinterpreting the bytes (making negatives into positives).
// It should get optimized away.
uint64_t bigEValue;
memcpy(&bigEValue, &value, sizeof(bigEValue));
bigEValue = leToBe64(bigEValue);
pack_basic(sock, 0xd3, &bigEValue, sizeof(bigEValue));
}
void pack_float(int sock, float value) {
// Need to use memcpy to do a direct copy without reinterpreting the bytes. It should get optimized away.
uint32_t bigEValue;
memcpy(&bigEValue, &value, sizeof(bigEValue));
bigEValue = htonl(bigEValue);
pack_basic(sock, 0xca, &bigEValue, sizeof(bigEValue));
}
// Return true if successful
bool pack_fixstr(int sock, char *string) {
// Make sure that the length is less than 32
size_t length = strlen(string);
if(length >= 32) {
logg("Tried to send a fixstr longer than 31 bytes!");
return false;
}
uint8_t format = (uint8_t) (0xA0 | length);
swrite(sock, &format, sizeof(format));
swrite(sock, string, length);
return true;
}
// Return true if successful
bool pack_str32(int sock, char *string) {
// Make sure that the length is less than 4294967296
size_t length = strlen(string);
if(length >= 2147483648u) {
logg("Tried to send a str32 longer than 2147483647 bytes!");
return false;
}
uint8_t format = 0xdb;
swrite(sock, &format, sizeof(format));
uint32_t bigELength = htonl((uint32_t) length);
swrite(sock, &bigELength, sizeof(bigELength));
swrite(sock, string, length);
return true;
}
void pack_map16_start(int sock, uint16_t length) {
uint8_t format = 0xde;
swrite(sock, &format, sizeof(format));
uint16_t bigELength = htons(length);
swrite(sock, &bigELength, sizeof(bigELength));
}