StreamSocketConnection::read()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.6666
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PHPFastCGI\FastCGIDaemon\Driver\Userland\Connection;
6
7
use PHPFastCGI\FastCGIDaemon\Driver\Userland\Exception\ConnectionException;
8
9
/**
10
 * The default implementation of the ConnectionInterface using stream socket
11
 * resources.
12
 */
13
final class StreamSocketConnection implements ConnectionInterface
14
{
15
    /**
16
     * @var bool
17
     */
18
    private $closed;
19
20
    /**
21
     * @var resource
22
     */
23
    private $socket;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param resource $socket The stream socket to wrap
29
     */
30
    public function __construct($socket)
31
    {
32
        $this->closed = false;
33
34
        $this->socket = $socket;
35
    }
36
37
    /**
38
     * Creates a formatted exception from the last error that occurecd.
39
     *
40
     * @param string $function The function that failed
41
     *
42
     * @return ConnectionException
43
     */
44
    protected function createExceptionFromLastError(string $function): ConnectionException
45
    {
46
        $this->close();
47
48
        return new ConnectionException($function.' failed');
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function read(int $length): string
55
    {
56
        if ($this->isClosed()) {
57
            throw new ConnectionException('Connection has been closed');
58
        }
59
60
        if (0 === $length) {
61
            return '';
62
        }
63
64
        $buffer = @fread($this->socket, $length);
65
66
        if (empty($buffer)) {
67
            throw $this->createExceptionFromLastError('fread');
68
        }
69
70
        return $buffer;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function write(string $buffer): void
77
    {
78
        if ($this->isClosed()) {
79
            throw new ConnectionException('Connection has been closed');
80
        }
81
82
        if (false == @fwrite($this->socket, $buffer) && !empty($buffer)) {
83
            throw $this->createExceptionFromLastError('fwrite');
84
        }
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function isClosed(): bool
91
    {
92
        return $this->closed;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function close(): void
99
    {
100
        if (!$this->isClosed()) {
101
            fclose($this->socket);
102
103
            $this->socket = null;
104
            $this->closed = true;
105
        }
106
    }
107
}
108