From b359745169616b7f4132cac397e723f70fb64ab3 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sun, 13 Aug 2023 19:07:56 -0400
Subject: [PATCH] Added SDLNet_CompareAddresses.
This is generally useful for "are these two addresses the same thing?"
but also suitable for using as a compare callback for SDL_qsort.
---
SDL_net.c | 34 ++++++++++++++++++++++++++++++++++
SDL_net.h | 2 +-
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/SDL_net.c b/SDL_net.c
index afbc962..17542e3 100644
--- a/SDL_net.c
+++ b/SDL_net.c
@@ -373,6 +373,40 @@ const char *SDLNet_GetAddressString(SDLNet_Address *addr)
return addr ? (const char *) SDL_AtomicGetPtr((void **) &addr->human_readable) : NULL;
}
+int SDLNet_CompareAddresses(const SDLNet_Address *sdlneta, const SDLNet_Address *sdlnetb)
+{
+ const struct addrinfo *a;
+ const struct addrinfo *b;
+
+ if (sdlneta == sdlnetb) { // same pointer?
+ return 0;
+ } else if (sdlneta && !sdlnetb) {
+ return -1;
+ } else if (!sdlneta && sdlnetb) {
+ return 1;
+ }
+
+ a = sdlneta->ainfo;
+ b = sdlnetb->ainfo;
+ if (a == b) { // same pointer?
+ return 0;
+ } else if (a && !b) {
+ return -1;
+ } else if (!a && b) {
+ return 1;
+ } else if (a->ai_family < b->ai_family) {
+ return -1;
+ } else if (a->ai_family > b->ai_family) {
+ return 1;
+ } else if (a->ai_addrlen < b->ai_addrlen) {
+ return -1;
+ } else if (a->ai_addrlen > b->ai_addrlen) {
+ return 1;
+ }
+
+ return SDL_memcmp(a->ai_addr, b->ai_addr, a->ai_addrlen);
+}
+
SDLNet_Address *SDLNet_RefAddress(SDLNet_Address *addr)
{
if (addr) {
diff --git a/SDL_net.h b/SDL_net.h
index b803b26..2cf34d1 100644
--- a/SDL_net.h
+++ b/SDL_net.h
@@ -32,7 +32,7 @@ extern DECLSPEC const char * SDLCALL SDLNet_GetAddressString(SDLNet_Address *add
extern DECLSPEC SDLNet_Address *SDLCALL SDLNet_RefAddress(SDLNet_Address *address); /* +1 refcount; SDLNet_ResolveHost starts at 1. Returns `address` for convenience. */
extern DECLSPEC void SDLCALL SDLNet_UnrefAddress(SDLNet_Address *address); /* when totally unref'd, gets freed. */
extern DECLSPEC void SDLCALL SDLNet_SimulateAddressResolutionLoss(int percent_loss); /* make resolutions delay at random, fail some percent of them. */
-
+extern DECLSPEC int SDLCALL SDLNet_CompareAddresses(const SDLNet_Address *a, const SDLNet_Address *b); /* can be used with SDL_qsort. */
extern DECLSPEC SDLNet_Address **SDLCALL SDLNet_GetLocalAddresses(int *num_addresses); /* returns NULL-terminated array of SDLNet_Address*, of all known interfaces. */
extern DECLSPEC void SDLCALL SDLNet_FreeLocalAddresses(SDLNet_Address **addresses); /* unrefs each address, frees array. */