Passed
Push — master ( 487089...443b76 )
by Chris
03:30
created

ms_to_secs_usecs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace DaveRandom\LibLifxLan\Examples;
4
5
use DaveRandom\Network\IPEndpoint;
6
7
/**
8
 * @param IPEndpoint $localEndpoint
9
 * @return resource
10
 */
11
function udp_create_socket(IPEndpoint $localEndpoint)
12
{
13
    $ctx = \stream_context_create(['socket' => ['so_broadcast' => true]]);
14
15
    if (!$socket = @\stream_socket_server('udp://' . $localEndpoint, $errNo, $errStr, \STREAM_SERVER_BIND, $ctx)) {
16
        throw new \RuntimeException("Failed to create local socket: {$errNo}: {$errStr}");
17
    }
18
19
    return $socket;
20
}
21
22
/**
23
 * @param int $timeoutMs
24
 * @return int[]
25
 */
26
function ms_to_secs_usecs(?int $timeoutMs): array
27
{
28
    return $timeoutMs !== null
29
        ? [(int)($timeoutMs / 1000), ($timeoutMs % 1000) * 1000]
30
        : [null, null];
31
}
32
33
/**
34
 * @param resource $socket
35
 * @param int $timeoutMs
36
 * @return array|null
37
 */
38
function udp_await_packet($socket, int $timeoutMs = null): ?array
39
{
40
    $r = [$socket];
41
    $w = $e = null;
42
43
    [$timeoutSecs, $timeoutUsecs] = ms_to_secs_usecs($timeoutMs);
44
45
    if (false === $count = \stream_select($r, $w, $e, $timeoutSecs, $timeoutUsecs ?? 0)) {
0 ignored issues
show
Bug introduced by
$w of type null is incompatible with the type array expected by parameter $write of stream_select(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
    if (false === $count = \stream_select($r, /** @scrutinizer ignore-type */ $w, $e, $timeoutSecs, $timeoutUsecs ?? 0)) {
Loading history...
Bug introduced by
$e of type null is incompatible with the type array expected by parameter $except of stream_select(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
    if (false === $count = \stream_select($r, $w, /** @scrutinizer ignore-type */ $e, $timeoutSecs, $timeoutUsecs ?? 0)) {
Loading history...
46
        throw new \RuntimeException("select() failed!");
47
    }
48
49
    if ($count === 0) {
50
        return null;
51
    }
52
53
    $data = \stream_socket_recvfrom($socket, 1024, 0, $address);
54
55
    return [$data, IPEndpoint::parse($address)];
56
}
57
58
/**
59
 * @param resource $socket
60
 * @param int $timeoutMs
61
 * @return array[]
62
 */
63
function udp_await_packets($socket, int $timeoutMs): array
64
{
65
    $packets = [];
66
67
    $start = \microtime(true);
68
    $remaining = $timeoutMs;
69
70
    do {
71
        if (null === $buffer = udp_await_packet($socket, $remaining)) {
72
            break;
73
        }
74
75
        $packets[] = $buffer;
76
        $remaining = (int)($timeoutMs - ((\microtime(true) - $start) * 1000));
77
    } while ($remaining > 0);
78
79
    return $packets;
80
}
81