net/SocketAddress: add CastTo()
This commit is contained in:
		 Max Kellermann
					Max Kellermann
				
			
				
					committed by
					
						 Max Kellermann
						Max Kellermann
					
				
			
			
				
	
			
			
			 Max Kellermann
						Max Kellermann
					
				
			
						parent
						
							32ce9ce919
						
					
				
				
					commit
					273771ffec
				
			| @@ -31,15 +31,9 @@ | ||||
|  | ||||
| #include <cassert> | ||||
|  | ||||
| static const struct sockaddr_in * | ||||
| CastToIPv4(const struct sockaddr *p) noexcept | ||||
| { | ||||
| 	assert(p->sa_family == AF_INET); | ||||
|  | ||||
| 	/* cast through void to work around the bogus alignment warning */ | ||||
| 	const void *q = reinterpret_cast<const void *>(p); | ||||
| 	return reinterpret_cast<const struct sockaddr_in *>(q); | ||||
| } | ||||
|  | ||||
| IPv4Address::IPv4Address(SocketAddress src) noexcept | ||||
| 	:address(*CastToIPv4(src.GetAddress())) {} | ||||
| 	:address(src.CastTo<struct sockaddr_in>()) | ||||
| { | ||||
| 	assert(!src.IsNull()); | ||||
| 	assert(src.GetFamily() == AF_INET); | ||||
| } | ||||
|   | ||||
| @@ -171,9 +171,7 @@ public: | ||||
| 	 * only legal after verifying SocketAddress::GetFamily(). | ||||
| 	 */ | ||||
| 	static constexpr const IPv4Address &Cast(const SocketAddress src) noexcept { | ||||
| 		/* this reinterpret_cast works because this class is | ||||
| 		   just a wrapper for struct sockaddr_in */ | ||||
| 		return *(const IPv4Address *)(const void *)src.GetAddress(); | ||||
| 		return Cast(src.CastTo<struct sockaddr_in>()); | ||||
| 	} | ||||
|  | ||||
| 	constexpr operator SocketAddress() const noexcept { | ||||
|   | ||||
| @@ -34,18 +34,12 @@ | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| static const struct sockaddr_in6 * | ||||
| CastToIPv6(const struct sockaddr *p) noexcept | ||||
| { | ||||
| 	assert(p->sa_family == AF_INET6); | ||||
|  | ||||
| 	/* cast through void to work around the bogus alignment warning */ | ||||
| 	const void *q = reinterpret_cast<const void *>(p); | ||||
| 	return reinterpret_cast<const struct sockaddr_in6 *>(q); | ||||
| } | ||||
|  | ||||
| IPv6Address::IPv6Address(SocketAddress src) noexcept | ||||
| 	:address(*CastToIPv6(src.GetAddress())) {} | ||||
| 	:address(src.CastTo<struct sockaddr_in6>()) | ||||
| { | ||||
| 	assert(!src.IsNull()); | ||||
| 	assert(src.GetFamily() == AF_INET6); | ||||
| } | ||||
|  | ||||
| bool | ||||
| IPv6Address::IsAny() const noexcept | ||||
|   | ||||
| @@ -140,9 +140,7 @@ public: | ||||
| 	 * only legal after verifying SocketAddress::GetFamily(). | ||||
| 	 */ | ||||
| 	static constexpr const IPv6Address &Cast(const SocketAddress src) noexcept { | ||||
| 		/* this reinterpret_cast works because this class is | ||||
| 		   just a wrapper for struct sockaddr_in6 */ | ||||
| 		return *(const IPv6Address *)(const void *)src.GetAddress(); | ||||
| 		return Cast(src.CastTo<struct sockaddr_in6>()); | ||||
| 	} | ||||
|  | ||||
| 	constexpr operator SocketAddress() const noexcept { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * Copyright 2012-2020 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
| @@ -63,7 +63,7 @@ SocketAddress::GetLocalRaw() const noexcept | ||||
| 		/* not applicable */ | ||||
| 		return nullptr; | ||||
|  | ||||
| 	const auto sun = (const struct sockaddr_un *)GetAddress(); | ||||
| 	const auto *sun = &CastTo<struct sockaddr_un>(); | ||||
| 	const auto start = (const char *)sun; | ||||
| 	const auto path = sun->sun_path; | ||||
| 	const size_t header_size = path - start; | ||||
| @@ -159,10 +159,10 @@ SocketAddress::GetSteadyPart() const noexcept | ||||
|  | ||||
| #ifdef HAVE_TCP | ||||
| 	case AF_INET: | ||||
| 		return ::GetSteadyPart(*(const struct sockaddr_in *)(const void *)GetAddress()); | ||||
| 		return ::GetSteadyPart(CastTo<struct sockaddr_in>()); | ||||
|  | ||||
| 	case AF_INET6: | ||||
| 		return ::GetSteadyPart(*(const struct sockaddr_in6 *)(const void *)GetAddress()); | ||||
| 		return ::GetSteadyPart(CastTo<struct sockaddr_in6>()); | ||||
| #endif | ||||
|  | ||||
| 	default: | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * Copyright 2012-2020 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
| @@ -82,6 +82,19 @@ public: | ||||
| 		return address; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Cast the "sockaddr" pointer to a different address type, | ||||
| 	 * e.g. "sockaddr_in".  This is only legal after checking | ||||
| 	 * !IsNull() and GetFamily(). | ||||
| 	 */ | ||||
| 	template<typename T> | ||||
| 	constexpr const T &CastTo() const noexcept { | ||||
| 		/* cast through void to work around the bogus | ||||
| 		   alignment warning */ | ||||
| 		const void *q = reinterpret_cast<const void *>(address); | ||||
| 		return *reinterpret_cast<const T *>(q); | ||||
| 	} | ||||
|  | ||||
| 	constexpr size_type GetSize() const noexcept { | ||||
| 		return size; | ||||
| 	} | ||||
|   | ||||
| @@ -68,6 +68,19 @@ public: | ||||
| 		return (const struct sockaddr *)(const void *)&address; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Cast the "sockaddr" pointer to a different address type, | ||||
| 	 * e.g. "sockaddr_in".  This is only legal after checking | ||||
| 	 * GetFamily(). | ||||
| 	 */ | ||||
| 	template<typename T> | ||||
| 	constexpr const T &CastTo() const noexcept { | ||||
| 		/* cast through void to work around the bogus | ||||
| 		   alignment warning */ | ||||
| 		const void *q = reinterpret_cast<const void *>(&address); | ||||
| 		return *reinterpret_cast<const T *>(q); | ||||
| 	} | ||||
|  | ||||
| 	constexpr size_type GetCapacity() const noexcept { | ||||
| 		return sizeof(address); | ||||
| 	} | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2011-2019 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * Copyright 2011-2020 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
| @@ -85,7 +85,7 @@ ToString(SocketAddress address) noexcept | ||||
| #ifdef HAVE_UN | ||||
| 	if (address.GetFamily() == AF_LOCAL) | ||||
| 		/* return path of local socket */ | ||||
| 		return LocalAddressToString(*(const sockaddr_un *)address.GetAddress(), | ||||
| 		return LocalAddressToString(address.CastTo<struct sockaddr_un>(), | ||||
| 					    address.GetSize()); | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2011-2019 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * Copyright 2011-2020 Max Kellermann <max.kellermann@gmail.com> | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|   | ||||
		Reference in New Issue
	
	Block a user