Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## `6.x`

- Rename the whole-value output methods to `to*` (conversions), keeping `get*`
for component and property accessors. Keep the `get*` spellings as deprecated
aliases; `getBinary()` is exempt as the accessor of the canonical state.
- Detect embedding strategies via the new `Contracts\StrategyDetectionInterface`
deprecating the old `IpInterface::isEmbedded()` and associated methods.
- Convert IP addresses to and from integers: `fromInteger()`/`toInteger()` via
Expand All @@ -25,10 +28,12 @@
`fromProtocol()`/`fromBinary()`.
- Introduce `@experimental` capability interfaces under `Darsyn\IP\Contracts\`.
Their shape may change before `7.0`, but remains backwards compatible for `6.x`
- Allow overriding the global formatter per call by passing a
`Formatter\ProtocolFormatterInterface` as the first argument to
`IPv4::getDotAddress()`, `IPv6::getCompactedAddress()`,
`Multi::getDotAddress()` and `Multi::getProtocolAppropriateAddress()`.
- Allow overriding the global formatter per call via an optional
`Formatter\ProtocolFormatterInterface` parameter on `toDotAddress()`,
`toCompactedAddress()` and `toProtocolAppropriateAddress()` (deprecated
`get*` aliases accept the same argument, but any other value triggers a
deprecation notice and falls back to the global formatter instead of
throwing a `TypeError`).
- Move CIDR mask generation from the protected `AbstractIP::generateBinaryMask()`
to the public static `Util\Binary::mask()`.
- Performance: compute network masks (`getNetworkIp()` / `getBroadcastIp()`)
Expand Down
28 changes: 14 additions & 14 deletions docs/03-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ Human-readable format comes in 3 flavours:

### Dot Address

`getDotAddress()` is only available for `IPv4` and `Multi` classes. Calling
`getDotAddress()` on an instance of `Multi` that contains a version 6 address
`toDotAddress()` is only available for `IPv4` and `Multi` classes. Calling
`toDotAddress()` on an instance of `Multi` that contains a version 6 address
will result in a `WrongVersionException` being thrown.

```php
Expand All @@ -184,16 +184,16 @@ use Darsyn\IP\Exception;
$ip = IP::factory('127.0.0.1');

try {
echo $ip->getDotAddress(); // string("127.0.0.1")
echo $ip->toDotAddress(); // string("127.0.0.1")
} catch (Exception\WrongVersionException $e) {
echo 'Cannot convert a version 6 address to dot-notation!';
}
```

### Compacted Address

`getCompactedAddress()` is only available for `IPv6` and `Multi` classes.
Calling `getCompactedAddress()` on an instance of `Multi` that contains a
`toCompactedAddress()` is only available for `IPv6` and `Multi` classes.
Calling `toCompactedAddress()` on an instance of `Multi` that contains a
version 4 address will result in the IP address being converted to a version 6
address according to the embedding strategy.

Expand All @@ -202,13 +202,13 @@ address according to the embedding strategy.
use Darsyn\IP\Version\Multi as IP;

$ip = IP::factory('127.0.0.1');
echo $ip->getCompactedAddress(); // string("::ffff:7f00:1")
echo $ip->toCompactedAddress(); // string("::ffff:7f00:1")
```

### Expanded Address

`getExpandedAddress()` is only available for `IPv6` and `Multi` classes. Calling
`getExpandedAddress()` on an instance of `Multi` that contains a version 4
`toExpandedAddress()` is only available for `IPv6` and `Multi` classes. Calling
`toExpandedAddress()` on an instance of `Multi` that contains a version 4
address will result in the IP address being converted to a version 6 address
according to the embedding strategy.

Expand All @@ -217,12 +217,12 @@ according to the embedding strategy.
use Darsyn\IP\Version\Multi as IP;

$ip = IP::factory('127.0.0.1');
$ip->getExpandedAddress(); // string("0000:0000:0000:0000:0000:ffff:7f00:0001")
$ip->toExpandedAddress(); // string("0000:0000:0000:0000:0000:ffff:7f00:0001")
```

### Protocol Appropriate Address

`getProtocolAppropriateAddress()` is only available for the `Multi` class. If
`toProtocolAppropriateAddress()` is only available for the `Multi` class. If
the instance of `Multi` contains a version 4 address, it will be returned in
dot notation, otherwise it returns a compacted version 6 address.

Expand All @@ -231,7 +231,7 @@ dot notation, otherwise it returns a compacted version 6 address.
use Darsyn\IP\Version\Multi as IP;

$ip = IP::factory('::ffff:7f00:1');
$ip->getProtocolAppropriateAddress(); // string("127.0.0.1")
$ip->toProtocolAppropriateAddress(); // string("127.0.0.1")
```

### Binary
Expand Down Expand Up @@ -337,11 +337,11 @@ so `__toString()` is implemented independently (deferring to `toString()`). The
returned string is in protocol-appropriate notation and can be re-parsed via
`fromProtocol()`.

- String casting the `IPv4` class is the equivalent of `$ip->getDotAddress()`.
- String casting the `IPv4` class is the equivalent of `$ip->toDotAddress()`.
- String casting the `IPv6` class is the equivalent of
`$ip->getCompactedAddress()`.
`$ip->toCompactedAddress()`.
- String casting the `Multi` class is the equivalent of
`$ip->getProtocolAppropriateAddress()`.
`$ip->toProtocolAppropriateAddress()`.

```php
<?php
Expand Down
18 changes: 9 additions & 9 deletions docs/04-helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ use Darsyn\IP\Version\Multi as IP;
$ip = IP::factory('12.34.56.78');
// Get the network address of an IP address given a subnet mask.
$networkIp = $ip->getNetworkIp(19);
$networkIp->getProtocolAppropriateAddress(); // string("12.34.32.0")
$networkIp->toProtocolAppropriateAddress(); // string("12.34.32.0")
```

### Broadcast IP
Expand All @@ -133,7 +133,7 @@ use Darsyn\IP\Version\Multi as IP;
$ip = IP::factory('12.34.56.78');
// Get the broadcast address of an IP address given a subnet mask.
$broadcastIp = $ip->getBroadcastIp(19);
$broadcastIp->getProtocolAppropriateAddress(); // string("12.34.63.255")
$broadcastIp->toProtocolAppropriateAddress(); // string("12.34.63.255")
```

### Is IP in Range?
Expand Down Expand Up @@ -188,10 +188,10 @@ use Darsyn\IP\Version\IPv4 as IP;

$ip = IP::fromProtocol('12.34.56.78');
// Step forwards or backwards within the address space.
$ip->next()->getDotAddress(); // string("12.34.56.79")
$ip->previous()->getDotAddress(); // string("12.34.56.77")
$ip->offset(256)->getDotAddress(); // string("12.34.57.78")
$ip->offset(-79)->getDotAddress(); // string("12.34.55.255")
$ip->next()->toDotAddress(); // string("12.34.56.79")
$ip->previous()->toDotAddress(); // string("12.34.56.77")
$ip->offset(256)->toDotAddress(); // string("12.34.57.78")
$ip->offset(-79)->toDotAddress(); // string("12.34.55.255")
```

## `IPv6` vs `Multi`?
Expand Down Expand Up @@ -234,13 +234,13 @@ use Darsyn\IP\Version\Ipv6;
// Strategy is optional; defaults to Mapped unless
// Multi::setDefaultEmbeddingStrategy() called previously.
$ip = IPv6::fromEmbedded('127.0.0.1', new Mapped);
$ip->getCompactedAddress(); // string("::ffff:7f00:1")
$ip->toCompactedAddress(); // string("::ffff:7f00:1")

try {
$ip->getDotAddress();
$ip->toDotAddress();
} catch (\Error $e) {
// IPv6 addresses are not considered IPv4 addresses and
// therefore do not have the method getDotAddress().
// therefore do not have the method toDotAddress().
}
```

Expand Down
6 changes: 3 additions & 3 deletions docs/05-strategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ use Darsyn\IP\Version\Multi as IP;
$strategy = new Composite(new Mapped, Nat64::wellKnown());

// Addresses embedded under either scheme are recognised as version 4.
IP::factory('::ffff:7f00:1', $strategy)->getDotAddress(); // string("127.0.0.1")
IP::factory('64:ff9b::7f00:1', $strategy)->getDotAddress(); // string("127.0.0.1")
IP::factory('::ffff:7f00:1', $strategy)->toDotAddress(); // string("127.0.0.1")
IP::factory('64:ff9b::7f00:1', $strategy)->toDotAddress(); // string("127.0.0.1")

// But only the first strategy (here, Mapped) is ever used to pack a version 4
// address into version 6.
IP::factory('127.0.0.1', $strategy)->getCompactedAddress(); // string("::ffff:7f00:1")
IP::factory('127.0.0.1', $strategy)->toCompactedAddress(); // string("::ffff:7f00:1")
```
22 changes: 12 additions & 10 deletions docs/06-formatters.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ use Darsyn\IP\Version\Multi as IP;

IP::setProtocolFormatter(new NativeFormatter);
$ip = IP::factory('::ffff:c22:384e');
$ip->getCompactedAddress(); // string("::ffff:12.34.56.78")
$ip->toCompactedAddress(); // string("::ffff:12.34.56.78")
```

## Per-call formatter
`setProtocolFormatter()` changes the formatter globally for every IP object, the
formatting methods therefore accept an optional formatter as their
first argument, overriding the global formatter for that call alone:
- `Darsyn\IP\Version\IPv4::getDotAddress()`
- `Darsyn\IP\Version\IPv6::getCompactedAddress()`
- `Darsyn\IP\Version\Multi::getDotAddress()`
- `Darsyn\IP\Version\Multi::getProtocolAppropriateAddress()`
- `Darsyn\IP\Version\IPv4::toDotAddress()`
- `Darsyn\IP\Version\IPv6::toCompactedAddress()`
- `Darsyn\IP\Version\Multi::toDotAddress()`
- `Darsyn\IP\Version\Multi::toProtocolAppropriateAddress()`

```php
<?php
Expand All @@ -41,10 +41,12 @@ use Darsyn\IP\Version\IPv6 as IP;
IP::setProtocolFormatter(new ConsistentFormatter());
$ip = IP::factory('::ffff:c22:384e');

$ip->getCompactedAddress(); // string("::ffff:c22:384e")
$ip->getCompactedAddress(new NativeFormatter); // string("::ffff:12.34.56.78")
$ip->getCompactedAddress(); // string("::ffff:c22:384e")
$ip->toCompactedAddress(); // string("::ffff:c22:384e")
$ip->toCompactedAddress(new NativeFormatter); // string("::ffff:12.34.56.78")
$ip->toCompactedAddress(); // string("::ffff:c22:384e")
```

Passing any value that does not implement
`Darsyn\IP\Formatter\ProtocolFormatterInterface` will trigger a deprecation notice and fall back to the global formatter.
These methods declare the parameter as a nullable
`Darsyn\IP\Formatter\ProtocolFormatterInterface`, so passing any other value
throws a `TypeError`. Their deprecated `get*` counterparts accept the same
argument but trigger a deprecation notice and fall back to the global formatter.
2 changes: 1 addition & 1 deletion docs/07-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ embedding strategy on `Multi`, or to the global default set via
use Darsyn\IP\Version\Multi as IP;

$ip = IP::fromProtocol('::ffff:7f00:1');
$ip->getEmbeddedIp()->getDotAddress(); // string("127.0.0.1")
$ip->getEmbeddedIp()->toDotAddress(); // string("127.0.0.1")
```

## Detecting Address Types
Expand Down
8 changes: 5 additions & 3 deletions src/Contracts/Output4Interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@

namespace Darsyn\IP\Contracts;

use Darsyn\IP\Formatter\ProtocolFormatterInterface;

/**
* @experimental
*/
interface Output4Interface extends OutputInterface
{
/**
* Get Dot Address
* Convert to Dot Address Notation
*
* Convert an IP into an IPv4 dot-notation address string
* This method will NOT work with IPv6 addresses.
*
* @throws \Darsyn\IP\Exception\IpException
* @throws \Darsyn\IP\Exception\WrongVersionException
*/
public function getDotAddress(): string;
public function toDotAddress(?ProtocolFormatterInterface $formatter = null): string;

/**
* Get Integer
* Convert to Integer
*
* Convert an IP into its unsigned 32-bit integer value, between 0 and
* 4294967295. This method will NOT work with IPv6 addresses.
Expand Down
10 changes: 6 additions & 4 deletions src/Contracts/Output6Interface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,32 @@

namespace Darsyn\IP\Contracts;

use Darsyn\IP\Formatter\ProtocolFormatterInterface;

/**
* @experimental
*/
interface Output6Interface extends OutputInterface
{
/**
* Get Compacted Address
* Convert to Compacted Address Notation
*
* Converts an IP (regardless of version) into a compacted IPv6 address
* (including double-colons if appropriate).
*
* @throws \Darsyn\IP\Exception\IpException
*/
public function getCompactedAddress(): string;
public function toCompactedAddress(?ProtocolFormatterInterface $formatter = null): string;

/**
* Get Expanded Address
* Convert to Expanded Address Notation
*
* Converts an IP (regardless of version) address into a full IPv6 address
* (no double colons).
*
* @throws \Darsyn\IP\Exception\IpException
*/
public function getExpandedAddress(): string;
public function toExpandedAddress(): string;

/**
* Get the IP address as an array of the eight 16-bit segments (hextets).
Expand Down
13 changes: 10 additions & 3 deletions src/Version/IPv4.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Darsyn\IP\AbstractIP;
use Darsyn\IP\Exception;
use Darsyn\IP\Formatter\ProtocolFormatterInterface;
use Darsyn\IP\Util\Binary;
use Darsyn\IP\Util\MbString;

Expand Down Expand Up @@ -160,15 +161,21 @@ public static function isValid(string $ip): bool
return null !== static::tryFromProtocol($ip);
}

public function getDotAddress(/* ?ProtocolFormatterInterface $formatter = null */): string
public function toDotAddress(?ProtocolFormatterInterface $formatter = null): string
{
try {
return self::resolveProtocolFormatter(\func_get_args())->ntop($this->getBinary());
return ($formatter ?? self::getProtocolFormatter())->ntop($this->getBinary());
} catch (Exception\Formatter\FormatException $e) {
throw new Exception\IpException('An unknown error occurred internally.', 0, $e);
}
}

/** @deprecated Use toDotAddress() instead. */
public function getDotAddress(/* ?ProtocolFormatterInterface $formatter = null */): string
{
return $this->toDotAddress(self::resolveProtocolFormatter(\func_get_args()));
}

/** @return int<0, 4294967295> */
public function toInteger(): int
{
Expand Down Expand Up @@ -302,7 +309,7 @@ public function isFutureReserved(): bool

public function toString(): string
{
return $this->getDotAddress();
return $this->toDotAddress();
}

public function __toString(): string
Expand Down
21 changes: 17 additions & 4 deletions src/Version/IPv6.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Darsyn\IP\AbstractIP;
use Darsyn\IP\Exception;
use Darsyn\IP\Formatter\ProtocolFormatterInterface;
use Darsyn\IP\Strategy;
use Darsyn\IP\Strategy\EmbeddingStrategyInterface;
use Darsyn\IP\Util\Binary;
Expand Down Expand Up @@ -193,7 +194,7 @@ public function getEmbeddedIp(?EmbeddingStrategyInterface $strategy = null): IPv
return Multi::fromBinary($this->getBinary(), $strategy)->getEmbeddedIp();
}

public function getExpandedAddress(): string
public function toExpandedAddress(): string
{
// Convert the 16-byte binary sequence into a hexadecimal-string
// representation, insert a colon between every block of 4 characters,
Expand All @@ -202,15 +203,27 @@ public function getExpandedAddress(): string
return MbString::subString(\is_string($expanded) ? $expanded : '', 0, -1);
}

public function getCompactedAddress(/* ?ProtocolFormatterInterface $formatter = null */): string
/** @deprecated Use toExpandedAddress() instead. */
public function getExpandedAddress(): string
{
return $this->toExpandedAddress();
}

public function toCompactedAddress(?ProtocolFormatterInterface $formatter = null): string
{
try {
return self::resolveProtocolFormatter(\func_get_args())->ntop($this->getBinary());
return ($formatter ?? self::getProtocolFormatter())->ntop($this->getBinary());
} catch (Exception\Formatter\FormatException $e) {
throw new Exception\IpException('An unknown error occurred internally.', 0, $e);
}
}

/** @deprecated Use toCompactedAddress() instead. */
public function getCompactedAddress(/* ?ProtocolFormatterInterface $formatter = null */): string
{
return $this->toCompactedAddress(self::resolveProtocolFormatter(\func_get_args()));
}

public function getSegments(): array
{
$segments = [];
Expand Down Expand Up @@ -370,7 +383,7 @@ private function isIetfProtocolAssignment(): bool

public function toString(): string
{
return $this->getCompactedAddress();
return $this->toCompactedAddress();
}

public function __toString(): string
Expand Down
Loading