Ada
3.4.3
Fast spec-compliant URL parser
Toggle main menu visibility
Loading...
Searching...
No Matches
serializers.cpp
Go to the documentation of this file.
1
#include <array>
2
#include <charconv>
3
#include <string>
4
5
namespace
ada::serializers
{
6
7
void
find_longest_sequence_of_ipv6_pieces
(
8
const
std::array<uint16_t, 8>& address,
size_t
& compress,
9
size_t
& compress_length)
noexcept
{
10
for
(
size_t
i = 0; i < 8; i++) {
11
if
(address[i] == 0) {
12
size_t
next = i + 1;
13
while
(next != 8 && address[next] == 0) ++next;
14
const
size_t
count = next - i;
15
if
(compress_length < count) {
16
compress_length = count;
17
compress = i;
18
if
(next == 8)
break
;
19
i = next;
20
}
21
}
22
}
23
}
24
25
std::string
ipv6
(
const
std::array<uint16_t, 8>& address) {
26
size_t
compress_length = 0;
// The length of a long sequence of zeros.
27
size_t
compress = 0;
// The start of a long sequence of zeros.
28
find_longest_sequence_of_ipv6_pieces
(address, compress, compress_length);
29
30
if
(compress_length <= 1) {
31
// Optimization opportunity: Find a faster way then snprintf for imploding
32
// and return here.
33
compress = compress_length = 8;
34
}
35
36
std::string output(4 * 8 + 7 + 2,
'\0'
);
37
size_t
piece_index = 0;
38
char
* point = output.data();
39
char
* point_end = output.data() + output.size();
40
*point++ =
'['
;
41
while
(
true
) {
42
if
(piece_index == compress) {
43
*point++ =
':'
;
44
// If we skip a value initially, we need to write '::', otherwise
45
// a single ':' will do since it follows a previous ':'.
46
if
(piece_index == 0) {
47
*point++ =
':'
;
48
}
49
piece_index += compress_length;
50
if
(piece_index == 8) {
51
break
;
52
}
53
}
54
point = std::to_chars(point, point_end, address[piece_index], 16).ptr;
55
piece_index++;
56
if
(piece_index == 8) {
57
break
;
58
}
59
*point++ =
':'
;
60
}
61
*point++ =
']'
;
62
output.resize(point - output.data());
63
return
output;
64
}
65
66
std::string
ipv4
(
const
uint64_t address) {
67
std::string output(15,
'\0'
);
68
char
* point = output.data();
69
char
* point_end = output.data() + output.size();
70
point = std::to_chars(point, point_end, uint8_t(address >> 24)).ptr;
71
for
(
int
i = 2; i >= 0; i--) {
72
*point++ =
'.'
;
73
point = std::to_chars(point, point_end, uint8_t(address >> (i * 8))).ptr;
74
}
75
output.resize(point - output.data());
76
return
output;
77
}
78
79
}
// namespace ada::serializers
ada::serializers
IP address serialization functions.
ada::serializers::find_longest_sequence_of_ipv6_pieces
void find_longest_sequence_of_ipv6_pieces(const std::array< uint16_t, 8 > &address, size_t &compress, size_t &compress_length) noexcept
Definition
serializers.cpp:7
ada::serializers::ipv6
std::string ipv6(const std::array< uint16_t, 8 > &address)
Definition
serializers.cpp:25
ada::serializers::ipv4
std::string ipv4(uint64_t address)
Definition
serializers.cpp:66