Completed
Push — master ( d1d02b...e3e5bf )
by Maik
02:45
created

Socket   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 225
Duplicated Lines 25.78 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 61.25%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 29
lcom 1
cbo 2
dl 58
loc 225
ccs 49
cts 80
cp 0.6125
rs 10
c 1
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A open() 0 9 2
A __destruct() 0 4 1
A close() 0 7 2
B isWriteable() 29 29 5
A count() 0 4 1
A read() 0 16 4
A write() 0 14 3
A getEndpoint() 0 4 1
A flush() 0 4 1
A isOpen() 0 4 1
A reset() 0 11 2
B ready() 29 29 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * This file is part of the PHP Generics package.
5
 *
6
 * @package Generics
7
 */
8
namespace Generics\Socket;
9
10
use Generics\Streams\SocketStream;
11
use Generics\ResetException;
12
use Exception;
13
14
/**
15
 * This abstract class provides basic socket functionality
16
 *
17
 * @author Maik Greubel <[email protected]>
18
 */
19
abstract class Socket implements SocketStream
20
{
21
22
    /**
23
     * The socket handle
24
     *
25
     * @var resource
26
     */
27
    protected $handle;
28
29
    /**
30
     * The socket endpoint
31
     *
32
     * @var Endpoint
33
     */
34
    protected $endpoint;
35
36
    /**
37
     * Create a new socket
38
     *
39
     * @param Endpoint $endpoint
40
     *            The endpoint for the socket
41
     */
42 7
    public function __construct(Endpoint $endpoint)
43
    {
44 7
        $this->endpoint = $endpoint;
45 7
        $this->open();
46 7
    }
47
    
48
    /**
49
     * Opens a socket
50
     * 
51
     * @throws SocketException
52
     */
53 7
    private function open()
54
    {
55 7
    	$this->handle = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
56
    	
57 7
    	if (! is_resource($this->handle)) {
58
    		$code = socket_last_error();
59
    		throw new SocketException(socket_strerror($code), array(), $code);
60
    	}
61 7
    }
62
63
    /**
64
     * Clean up
65
     */
66 7
    public function __destruct()
67
    {
68 7
        $this->close();
69 1
    }
70
71
    /**
72
     * {@inheritDoc}
73
     * @see \Generics\Streams\Stream::close()
74
     */
75 5
    public function close()
76
    {
77 5
        if (is_resource($this->handle)) {
78 5
            socket_close($this->handle);
79 5
            $this->handle = null;
80
        }
81 5
    }
82
83
    /**
84
     * {@inheritDoc}
85
     * @see \Generics\Streams\Stream::ready()
86
     */
87 4 View Code Duplication
    public function ready()
88
    {
89 4
        if (! is_resource($this->handle)) {
90 1
            return false;
91
        }
92
93
        $read = array(
94 3
            $this->handle
95
        );
96 3
        $write = null;
97 3
        $except = null;
98
99 3
        $num = @socket_select($read, $write, $except, 0);
100
101 3
        if ($num === false) {
102
            $code = socket_last_error($this->handle);
103
            throw new SocketException(socket_strerror($code), array(), $code);
104
        }
105
106 3
        if ($num < 1) {
107 3
            return false;
108
        }
109
110 2
        if (! in_array($this->handle, $read)) {
111
            return false;
112
        }
113
114 2
        return true;
115
    }
116
117
    /**
118
     * {@inheritDoc}
119
     * @see \Generics\Streams\OutputStream::isWriteable()
120
     */
121 1 View Code Duplication
    public function isWriteable()
122
    {
123 1
        if (! is_resource($this->handle)) {
124
            return false;
125
        }
126
127 1
        $read = null;
128
        $write = array(
129 1
            $this->handle
130
        );
131 1
        $except = null;
132
133 1
        $num = @socket_select($read, $write, $except, 0, 0);
134
135 1
        if ($num === false) {
136
            $code = socket_last_error($this->handle);
137
            throw new SocketException(socket_strerror($code), array(), $code);
138
        }
139
140 1
        if ($num < 1) {
141
            return false;
142
        }
143
144 1
        if (! in_array($this->handle, $write)) {
145
            return false;
146
        }
147
148 1
        return true;
149
    }
150
151
    /**
152
     * {@inheritDoc}
153
     * @see \Countable::count()
154
     */
155
    public function count()
156
    {
157
        throw new SocketException("Cannot count elements of socket");
158
    }
159
160
    /**
161
     * {@inheritDoc}
162
     * @see \Generics\Streams\InputStream::read()
163
     */
164 2
    public function read($length = 1, $offset = null)
165
    {
166 2
        if (($buf = @socket_read($this->handle, $length)) === false) {
167
            $buf = null;
168
            $code = socket_last_error();
169
            if ($code != 0) {
170
                if ($code != 10053) {
171
                	throw new SocketException(socket_strerror($code), array(), $code);
172
                } else {
173
                    $this->handle = null;
174
                }
175
            }
176
        }
177
178 2
        return $buf;
179
    }
180
181
    /**
182
     * {@inheritDoc}
183
     * @see \Generics\Streams\OutputStream::write()
184
     */
185 3
    public function write($buffer)
186
    {
187 3
        if (($written = @socket_write($this->handle, "{$buffer}\0")) === false) {
188
            $code = socket_last_error();
189
            throw new SocketException(socket_strerror($code), array(), $code);
190
        }
191
192 3
        if ($written != strlen($buffer) + 1) {
193
            throw new SocketException("Could not write all {bytes} bytes to socket ({written} written)", array(
194
                'bytes' => strlen($buffer),
195
                'written' => $written
196
            ));
197
        }
198 3
    }
199
200
    /**
201
     * Get the socket endpoint
202
     *
203
     * @return \Generics\Socket\Endpoint
204
     */
205 3
    public function getEndpoint()
206
    {
207 3
        return $this->endpoint;
208
    }
209
210
    /**
211
     * {@inheritDoc}
212
     * @see \Generics\Streams\OutputStream::flush()
213
     */
214
    public function flush()
215
    {
216
        // There is no function to flush a socket. This is only possible for file descriptors.
217
    }
218
    
219
    /**
220
     * {@inheritDoc}
221
     * @see \Generics\Streams\Stream::isOpen()
222
     */
223 1
    public function isOpen()
224
    {
225 1
    	return is_resource($this->handle);
226
    }
227
    
228
    /**
229
     * {@inheritDoc}
230
     * @see \Generics\Resettable::reset()
231
     */
232
    public function reset()
233
    {
234
    	try {
235
	    	$this->close();
236
	    	$this->open();
237
    	}
238
    	catch(Exception $ex)
239
    	{
240
    		throw new ResetException($ex->getMessage(), array(), $ex->getCode(), $ex);
241
    	}
242
    }
243
}
244