Ada 3.1.0
Fast spec-compliant URL parser
Loading...
Searching...
No Matches
serializers.cpp
Go to the documentation of this file.
1#include <array>
2#include <charconv>
3#include <string>
4
5namespace ada::serializers {
6
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
25std::string ipv6(const std::array<uint16_t, 8>& address) noexcept {
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
66std::string ipv4(const uint64_t address) noexcept {
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
Includes the definitions for URL serializers.
std::string ipv6(const std::array< uint16_t, 8 > &address) noexcept
void find_longest_sequence_of_ipv6_pieces(const std::array< uint16_t, 8 > &address, size_t &compress, size_t &compress_length) noexcept
std::string ipv4(uint64_t address) noexcept