| /* |
| * Copyright (c) 2021 Apple Inc. All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "mdns_addr_tailq.h" |
| |
| #ifdef __APPLE__ |
| #include <AssertMacros.h> |
| #endif // __APPLE__ |
| |
| #include "mdns_strict.h" |
| |
| //====================================================================================================================== |
| // MARK: - Functions |
| |
| mdns_addr_tailq_t * |
| mdns_addr_tailq_create(void) |
| { |
| mdns_addr_tailq_t * const me = mdns_calloc(1, sizeof(*me)); |
| require(me != NULL, exit); |
| |
| STAILQ_INIT(me); |
| exit: |
| return me; |
| } |
| //====================================================================================================================== |
| |
| void |
| mdns_addr_tailq_dispose(mdns_addr_tailq_t * NONNULL me) |
| { |
| mdns_addr_with_port_t * n1 = STAILQ_FIRST(me); |
| mdns_addr_with_port_t * n2; |
| while (n1 != NULL) { |
| n2 = STAILQ_NEXT(n1, __entries); |
| mdns_free(n1); |
| n1 = n2; |
| } |
| mdns_addr_tailq_t * me_temp = me; |
| mdns_free(me_temp); |
| } |
| |
| //====================================================================================================================== |
| |
| bool |
| mdns_addr_tailq_empty(const mdns_addr_tailq_t * const NONNULL me) |
| { |
| return STAILQ_EMPTY(me); |
| } |
| |
| //====================================================================================================================== |
| |
| const mdns_addr_with_port_t * NULLABLE |
| mdns_addr_tailq_add_front(mdns_addr_tailq_t * const NONNULL me, const mDNSAddr * const NONNULL address, |
| const mDNSIPPort port) |
| { |
| mdns_addr_with_port_t * const addr_with_port = mdns_calloc(1, sizeof(*addr_with_port)); |
| require(addr_with_port != NULL, exit); |
| |
| addr_with_port->address = *address; |
| addr_with_port->port = port; |
| |
| STAILQ_INSERT_HEAD(me, addr_with_port, __entries); |
| |
| exit: |
| return addr_with_port; |
| } |
| |
| //====================================================================================================================== |
| |
| const mdns_addr_with_port_t * NULLABLE |
| mdns_addr_tailq_add_back(mdns_addr_tailq_t * const NONNULL me, const mDNSAddr * const NONNULL address, |
| const mDNSIPPort port) |
| { |
| mdns_addr_with_port_t * const addr_with_port = mdns_calloc(1, sizeof(*addr_with_port)); |
| require(addr_with_port != NULL, exit); |
| |
| addr_with_port->address = *address; |
| addr_with_port->port = port; |
| |
| STAILQ_INSERT_TAIL(me, addr_with_port, __entries); |
| |
| exit: |
| return addr_with_port; |
| } |
| |
| //====================================================================================================================== |
| |
| const mdns_addr_with_port_t * NULLABLE |
| mdns_addr_tailq_get_front(const mdns_addr_tailq_t * const NONNULL me) |
| { |
| return STAILQ_FIRST(me); |
| } |
| |
| //====================================================================================================================== |
| |
| void |
| mdns_addr_tailq_remove_front(mdns_addr_tailq_t * const NONNULL me) |
| { |
| mdns_addr_with_port_t * n = STAILQ_FIRST(me); |
| STAILQ_REMOVE_HEAD(me, __entries); |
| mdns_free(n); |
| } |
| |
| //====================================================================================================================== |
| |
| bool |
| mdns_addr_tailq_remove(mdns_addr_tailq_t * const NONNULL me, const mDNSAddr * const NONNULL address, |
| const mDNSIPPort port) |
| { |
| bool found; |
| require_action(!mdns_addr_tailq_empty(me), exit, found = false); |
| |
| mdns_addr_with_port_t * addr_with_port; |
| mdns_addr_with_port_t * addr_with_port_temp; |
| found = false; |
| STAILQ_FOREACH_SAFE(addr_with_port, me, __entries, addr_with_port_temp) { |
| if (mDNSVal16(port) != mDNSVal16(addr_with_port->port)) { |
| continue; |
| } |
| if (!mDNSSameAddress(address, &addr_with_port->address)) { |
| continue; |
| } |
| found = true; |
| |
| STAILQ_REMOVE(me, addr_with_port, mdns_addr_with_port, __entries); |
| mdns_free(addr_with_port); |
| break; |
| } |
| |
| exit: |
| return found; |
| } |
| |
| //====================================================================================================================== |
| |
| bool |
| mdns_addr_with_port_equal(const mdns_addr_with_port_t * const NONNULL addr_1, |
| const mdns_addr_with_port_t * const NONNULL addr_2) |
| { |
| bool equal; |
| |
| if (addr_1 == addr_2) { |
| equal = true; |
| goto exit; |
| } |
| |
| if (mDNSVal16(addr_1->port) != mDNSVal16(addr_2->port)) { |
| equal = false; |
| goto exit; |
| } |
| |
| if (!mDNSSameAddress(&addr_1->address, &addr_2->address)) { |
| equal = false; |
| goto exit; |
| } |
| |
| equal = true; |
| exit: |
| return equal; |
| } |