The function converts from IPv4/6 addresses to their string forms. The complication comes from the v6 part due to address compression and v4-mapping. The traditional implementation of this is to sprintf the address into a temporary buffer. We cannot do that here due to the ban on calling other entry points. Using the lower-level constructs is possible, but a straight forward application of IntegerToString does not result in particularly impressive performance: 50%-100% slower than what's in this patch (and slower than glibc). It also doesn't make the code much smaller as the majority of it is dedicated to v6 compression. The IPv6 implementation uses a temporary buffer, but it also has a fast-path which skips the buffer if its size is guaranteed to be sufficient. The IPv4 implementation also has a fast path, but the fallback here is to compute the precise length of the string instead (the buffer option was slower and IPv4 makes it easier to compute the precise length). The v6 compression code is unrolled to make it easier to optimize. While it is possible to write a single printing loop that handles all cases, its branchiness does not make it amenable for optimization. The resulting function is faster than its glibc counterpart, though the exact ratio varies depending on the input: - random IPv4: 15% faster - random IPv6: 6% faster - "::": 50% faster
42 lines
1.6 KiB
C++
42 lines
1.6 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file contains helper functions for parsing and manipulating network
|
|
/// addresses.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIBC_SRC___SUPPORT_NET_ADDRESS_H
|
|
#define LLVM_LIBC_SRC___SUPPORT_NET_ADDRESS_H
|
|
|
|
#include "hdr/types/struct_in6_addr.h"
|
|
#include "hdr/types/struct_in_addr.h"
|
|
#include "src/__support/CPP/optional.h"
|
|
#include "src/__support/CPP/span.h"
|
|
#include "src/__support/macros/config.h"
|
|
|
|
namespace LIBC_NAMESPACE_DECL {
|
|
namespace net {
|
|
|
|
cpp::optional<in_addr_t> inet_addr(const char *cp);
|
|
|
|
/// Writes a string representation (including the terminating \0) of the
|
|
/// provided address into the destination buffer. In case of error, returns
|
|
/// false and does not modify the buffer.
|
|
[[nodiscard]] bool ipv4_to_str(const struct in_addr &src, cpp::span<char> dst);
|
|
|
|
/// Writes a string representation (including the terminating \0) of the
|
|
/// provided address into the destination buffer. In case of error, returns
|
|
/// false and does not modify the buffer.
|
|
[[nodiscard]] bool ipv6_to_str(const struct in6_addr &src, cpp::span<char> dst);
|
|
|
|
} // namespace net
|
|
} // namespace LIBC_NAMESPACE_DECL
|
|
|
|
#endif // LLVM_LIBC_SRC___SUPPORT_NET_ADDRESS_H
|