index/src/Net/IPEndPoint.php

102 lines
2.9 KiB
PHP

<?php
// IPEndPoint.php
// Created: 2021-04-30
// Updated: 2024-08-01
namespace Index\Net;
use InvalidArgumentException;
use Index\XString;
/**
* Represents an IP address end point.
*/
class IPEndPoint extends EndPoint {
private IPAddress $address;
private int $port;
/**
* @param IPAddress $address IP address.
* @param int $port Network port, 0 to leave default.
* @throws InvalidArgumentException If $port is less than 0 or greater than 65535.
*/
public function __construct(IPAddress $address, int $port) {
if($port < 0 || $port > 0xFFFF)
throw new InvalidArgumentException('$port is not a valid port number.');
$this->address = $address;
$this->port = $port;
}
/**
* Returns the IP address.
*
* @return IPAddress IP address.
*/
public function getAddress(): IPAddress {
return $this->address;
}
/**
* Whether a port is specified.
*
* @return bool true if the port number is greater than 0.
*/
public function hasPort(): bool {
return $this->port > 0;
}
/**
* Retrieves port number.
*
* @return int Network port number.
*/
public function getPort(): int {
return $this->port;
}
public function __serialize(): array {
return [$this->address, $this->port];
}
public function __unserialize(array $serialized): void {
$this->address = $serialized[0];
$this->port = $serialized[1];
}
public function equals(mixed $other): bool {
return $other instanceof IPEndPoint
&& $this->port === $other->port
&& $this->address->equals($other->address);
}
/**
* Attempts to parse a string into an IP end point.
*
* @param string $string String to parse.
* @throws InvalidArgumentException If $string does not contain a valid IP end point string.
* @return IPEndPoint Representation of the given string.
*/
public static function parse(string $string): IPEndPoint {
if(str_starts_with($string, '[')) { // IPv6
$closing = strpos($string, ']');
if($closing === false)
throw new InvalidArgumentException('$string is not a valid IP end point.');
$ip = substr($string, 1, $closing - 1);
$port = (int)substr($string, $closing + 2);
} else { // IPv4
$parts = explode(':', $string, 2);
if(count($parts) < 2)
throw new InvalidArgumentException('$string is not a valid IP end point.');
$ip = $parts[0];
$port = (int)$parts[1];
}
return new IPEndPoint(IPAddress::parse($ip), $port);
}
public function __toString(): string {
if($this->port < 1)
return $this->address->getAddress();
return $this->address->getAddress() . ':' . $this->port;
}
}