Skip to content

Commit

Permalink
merge address_ and scope_id_ memebers in address_or_scope_id_ member
Browse files Browse the repository at this point in the history
  • Loading branch information
gammasoft71 committed Feb 6, 2025
1 parent 5f947db commit 3543d1d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 34 deletions.
5 changes: 2 additions & 3 deletions src/xtd.core/include/xtd/net/ip_address.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace xtd {
/// @{
/// @brief Initializes a new instance of the xtd::net::ip_address.
/// @remarks ip_address is initialized by default value xtd::net::ip_address::none.
ip_address() = default;
ip_address();
/// @brief Initializes a new instance of the xtd::net::ip_address class with the address specified as an uint32.
/// @param address The value of the IP address. For example, the value 0x2414188F in big-endian format would be the IP address "143.24.20.36".
explicit ip_address(uint32 address);
Expand Down Expand Up @@ -314,9 +314,8 @@ namespace xtd {
friend xtd::net::sockets::socket;
static constexpr size_t number_of_numbers_ = 8;
ip_address(const std::vector<uint16>& numbers, uint32 scope_id);
uint32 address_ = 0xFFFFFFFF;
uint32 address_or_scope_id_ = 0;
std::vector<uint16> numbers_ = std::vector<uint16>(number_of_numbers_);
uint32 scope_id_ = 0;
sockets::address_family address_family_ = sockets::address_family::inter_network;
};
}
Expand Down
62 changes: 33 additions & 29 deletions src/xtd.core/src/xtd/net/ip_address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ const ip_address ip_address::ip_v6_none {std::vector<xtd::byte> {0, 0, 0, 0, 0,
const ip_address ip_address::loopback {0x0100007FLL};
const ip_address ip_address::none {0xFFFFFFFFLL};

ip_address::ip_address() : address_or_scope_id_ {0xFFFFFFFF} {
}

ip_address::ip_address(uint32 address) {
address_ = static_cast<int32>(address);
address_or_scope_id_ = static_cast<int32>(address);
}

ip_address::ip_address(const std::vector<xtd::byte>& address) {
if (address.size() != 4 && address.size() != 16) throw argument_exception {};

if (address.size() == 4) {
address_family_ = sockets::address_family::inter_network;
address_ = ((address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]) & 0x0FFFFFFFF);
address_or_scope_id_ = ((address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]) & 0x0FFFFFFFF);
}

if (address.size() == 16) {
Expand All @@ -40,15 +43,15 @@ ip_address::ip_address(const std::vector<xtd::byte>& address) {
ip_address::ip_address(const std::vector<xtd::byte>& address, uint32 scope_id) : address_family_(sockets::address_family::inter_network_v6) {
if (address.size() != 16) throw argument_exception {};

scope_id_ = scope_id;
address_or_scope_id_ = scope_id;
for (auto index = 0_z; index < number_of_numbers_; index++)
numbers_[index] = (static_cast<int16>(address[index * 2]) << 8) + static_cast<int16>(address[(index * 2) + 1]);
}

ip_address::ip_address(xtd::byte quad_part_address1, xtd::byte quad_part_address2, xtd::byte quad_part_address3, xtd::byte quad_part_address4) : address_((quad_part_address4 << 24 | quad_part_address3 << 16 | quad_part_address2 << 8 | quad_part_address1) & 0x0FFFFFFFF) {
ip_address::ip_address(xtd::byte quad_part_address1, xtd::byte quad_part_address2, xtd::byte quad_part_address3, xtd::byte quad_part_address4) : address_or_scope_id_((quad_part_address4 << 24 | quad_part_address3 << 16 | quad_part_address2 << 8 | quad_part_address1) & 0x0FFFFFFFF) {
}

ip_address::ip_address(const std::vector<uint16>& numbers, uint32 scope_id) : numbers_(numbers), scope_id_(scope_id), address_family_(sockets::address_family::inter_network_v6) {
ip_address::ip_address(const std::vector<uint16>& numbers, uint32 scope_id) : address_or_scope_id_(scope_id), numbers_(numbers), address_family_(sockets::address_family::inter_network_v6) {
}

sockets::address_family ip_address::address_family() const noexcept {
Expand Down Expand Up @@ -84,13 +87,13 @@ bool ip_address::is_ip_v6_teredo() const noexcept {

uint32 ip_address::scope_id() const {
if (address_family_ == sockets::address_family::inter_network) throw socket_exception(socket_error::operation_not_supported);
return scope_id_;
return address_or_scope_id_;
}

ip_address& ip_address::scope_id(uint32 value) {
if (address_family_ == sockets::address_family::inter_network) throw socket_exception(socket_error::operation_not_supported);

scope_id_ = static_cast<uint32>(value);
address_or_scope_id_ = static_cast<uint32>(value);
return *this;
}

Expand All @@ -99,29 +102,29 @@ bool ip_address::equals(const object& obj) const noexcept {
}

bool ip_address::equals(const ip_address& other) const noexcept {
return address_ == other.address_ && numbers_ == other.numbers_ && scope_id_ == other.scope_id_ && address_family_ == other.address_family_;
return address_or_scope_id_ == other.address_or_scope_id_ && numbers_ == other.numbers_ && address_or_scope_id_ == other.address_or_scope_id_ && address_family_ == other.address_family_;
}

size ip_address::get_hash_code() const noexcept {
auto result = hash_code {};
if (address_family_ == sockets::address_family::inter_network)
result.add(address_);
result.add(address_or_scope_id_);
else {
for (auto number : numbers_)
result.add(number);
result.add(scope_id_);
result.add(address_or_scope_id_);
}
result.add(address_family_);
return result.to_hash_code();
}

std::vector<xtd::byte> ip_address::get_address_bytes() const {
std::vector<xtd::byte> bytes;
auto bytes = std::vector<xtd::byte> {};
if (address_family_ == sockets::address_family::inter_network) {
bytes.push_back(static_cast<xtd::byte>(address_));
bytes.push_back(static_cast<xtd::byte>(address_ >> 8));
bytes.push_back(static_cast<xtd::byte>(address_ >> 16));
bytes.push_back(static_cast<xtd::byte>(address_ >> 24));
bytes.push_back(static_cast<xtd::byte>(address_or_scope_id_));
bytes.push_back(static_cast<xtd::byte>(address_or_scope_id_ >> 8));
bytes.push_back(static_cast<xtd::byte>(address_or_scope_id_ >> 16));
bytes.push_back(static_cast<xtd::byte>(address_or_scope_id_ >> 24));
return bytes;
}

Expand Down Expand Up @@ -168,24 +171,24 @@ uint64 ip_address::host_to_network_order(uint64 host) {
}

bool ip_address::is_loopback(const ip_address& address) {
if (address.address_family_ == sockets::address_family::inter_network) return static_cast<xtd::byte>(address.address_ & 0x00000000000000FF) == 0x7F;
if (address.address_family_ == sockets::address_family::inter_network) return static_cast<xtd::byte>(address.address_or_scope_id_ & 0x00000000000000FF) == 0x7F;
for (auto index = 0_z; index < number_of_numbers_ - 2; index++)
if (address.numbers_[index] != 0) return false;
return address.numbers_[7] == 1u;
}

ip_address ip_address::map_to_ip_v4() const noexcept {
if (address_family_ == sockets::address_family::inter_network) return *this;
uint32 address = (((static_cast<uint32>(numbers_[6]) & 0x0000FF00u) >> 8) | ((static_cast<uint32>(numbers_[6]) & 0x000000FFu) << 8)) | ((((static_cast<uint32>(numbers_[7]) & 0x0000FF00u) >> 8) | ((static_cast<uint32>(numbers_[7]) & 0x000000FFu) << 8)) << 16);
auto address = (((static_cast<uint32>(numbers_[6]) & 0x0000FF00u) >> 8) | ((static_cast<uint32>(numbers_[6]) & 0x000000FFu) << 8)) | ((((static_cast<uint32>(numbers_[7]) & 0x0000FF00u) >> 8) | ((static_cast<uint32>(numbers_[7]) & 0x000000FFu) << 8)) << 16);
return ip_address(address);
}

ip_address ip_address::map_to_ip_v6() const noexcept {
if (address_family_ == sockets::address_family::inter_network_v6) return *this;
std::vector<uint16> numbers(number_of_numbers_);
auto numbers = std::vector<uint16>(number_of_numbers_);
numbers[5] = 0xFFFF;
numbers[6] = static_cast<uint16>(((address_ & 0x0000FF00) >> 8) | ((address_ & 0x000000FF) << 8));
numbers[7] = static_cast<uint16>(((address_ & 0xFF000000) >> 24) | ((address_ & 0x00FF0000) >> 8));
numbers[6] = static_cast<uint16>(((address_or_scope_id_ & 0x0000FF00) >> 8) | ((address_or_scope_id_ & 0x000000FF) << 8));
numbers[7] = static_cast<uint16>(((address_or_scope_id_ & 0xFF000000) >> 24) | ((address_or_scope_id_ & 0x00FF0000) >> 8));
return ip_address(numbers, 0);
}

Expand Down Expand Up @@ -222,20 +225,21 @@ uint64 ip_address::network_to_host_order(uint64 network) {
}

ip_address ip_address::parse(const string& str) {
block_scope_(std::vector<string> address_parts = str.split('.')) {
block_scope_(auto address_parts = str.split('.')) {
if (address_parts.size() == 4) {
std::vector<xtd::byte> addresses(4);
for (auto index = 0_z; index < address_parts.size(); index++)
auto addresses = std::vector<xtd::byte>(4);
for (auto index = 0_z; index < address_parts.size(); ++index)
addresses[index] = xtd::parse<xtd::byte>(address_parts[index]);
return ip_address(addresses);
}
}

string work_ip_string = ((str[0] == '[' && str[str.size() - 1] == ']') ? str.substring(1, str.size() - 2) : str);
ip_address value;
auto work_ip_string = string((str[0] == '[' && str[str.size() - 1] == ']') ? str.substring(1, str.size() - 2) : str);
auto value = ip_address {};
value.address_or_scope_id_ = 0;
value.address_family_ = sockets::address_family::inter_network_v6;
if (work_ip_string.index_of('%') != work_ip_string.npos) {
value.scope_id_ = xtd::parse<uint32>(work_ip_string.substring(work_ip_string.index_of('%') + 1));
value.address_or_scope_id_ = xtd::parse<uint32>(work_ip_string.substring(work_ip_string.index_of('%') + 1));
work_ip_string = work_ip_string.remove(work_ip_string.index_of('%'));
};

Expand Down Expand Up @@ -263,8 +267,8 @@ string ip_address::to_string() const noexcept {
if (address_family_ == sockets::address_family::inter_network)
return string::join(".", get_address_bytes());

string str;
for (size_t index = 0; index < 8; ++index) {
auto str = string::empty_string;
for (auto index = size {0}; index < 8; ++index) {
if (index < 7 && numbers_[index] == 0 && numbers_[index + 1] == 0) {
if (index == 0) str = ":";
while (index < 7 && numbers_[index + 1] == 0) ++index;
Expand All @@ -274,7 +278,7 @@ string ip_address::to_string() const noexcept {
if (index < 7) str += ":";
}
}
if (scope_id_ != 0) str += string::format("%{}", scope_id_);
if (address_or_scope_id_ != 0) str += string::format("%{}", address_or_scope_id_);
return str;
}

Expand Down
4 changes: 2 additions & 2 deletions src/xtd.core/src/xtd/net/sockets/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,8 +908,8 @@ void socket::set_socket_option(xtd::net::sockets::linger_option option_value) {
void socket::set_socket_option(xtd::net::sockets::socket_option_name socket_option_name, const xtd::net::sockets::multicast_option& option_value) {
if (data_->handle == 0) throw object_closed_exception {};
if (socket_option_name != xtd::net::sockets::socket_option_name::add_membership && socket_option_name != xtd::net::sockets::socket_option_name::drop_membership) throw argument_exception {};
auto multicast_address = option_value.group().address_;
auto interface_index = option_value.local_address() != ip_address::none ? option_value.local_address().address_ : ip_address::host_to_network_order(option_value.interface_index());
auto multicast_address = option_value.group().address_or_scope_id_;
auto interface_index = option_value.local_address() != ip_address::none ? option_value.local_address().address_or_scope_id_ : ip_address::host_to_network_order(option_value.interface_index());
if (native::socket::set_socket_multicast_option(data_->handle, static_cast<int32>(socket_option_name), multicast_address, interface_index) != 0) throw socket_exception(get_last_error_());
}

Expand Down

0 comments on commit 3543d1d

Please sign in to comment.