SettingsFrame   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 111
Duplicated Lines 2.7 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 3
dl 3
loc 111
ccs 26
cts 26
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 3
A serializeBody() 0 9 2
A parseBody() 3 14 3
A getSettings() 0 4 1
A setSettings() 0 5 1

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
declare(strict_types=1);
3
namespace Hyphper\Frame;
4
5
use Hyphper\Frame\Exception\InvalidFrameException;
6
7
/**
8
 * The SETTINGS frame conveys configuration parameters that affect how
9
 * endpoints communicate. The parameters are either constraints on peer
10
 * behavior or preferences.
11
 *
12
 * Settings are not negotiated. Settings describe characteristics of the
13
 * sending peer, which are used by the receiving peer. Different values for
14
 * the same setting can be advertised by each peer. For example, a client
15
 * might set a high initial flow control window, whereas a server might set a
16
 * lower value to conserve resources.
17
 *
18
 * @package Hyphper\Frame
19
 */
20
class SettingsFrame extends \Hyphper\Frame
21
{
22
    protected $defined_flags = [Flag::ACK];
23
    protected $type = 0x04;
24
    protected $stream_association = self::NO_STREAM;
25
    protected $settings;
26
27
    /**
28
     * The byte that signals the SETTINGS_HEADER_TABLE_SIZE setting.
29
     */
30
    const HEADER_TABLE_SIZE = 0x01;
31
32
    /**
33
     * The byte that signals the SETTINGS_ENABLE_PUSH setting.
34
     */
35
    const ENABLE_PUSH = 0x02;
36
    /**
37
     * The byte that signals the SETTINGS_MAX_CONCURRENT_STREAMS setting.
38
     */
39
    const MAX_CONCURRENT_STREAMS = 0x03;
40
41
    /**
42
     * The byte that signals the SETTINGS_INITIAL_WINDOW_SIZE setting.
43
     */
44
    const INITIAL_WINDOW_SIZE = 0x04;
45
46
    /**
47
     * The byte that signals the SETTINGS_MAX_FRAME_SIZE setting.
48
     */
49
    const MAX_FRAME_SIZE = 0x05;
50
51
    /**
52
     * The byte that signals the SETTINGS_MAX_HEADER_LIST_SIZE setting.
53
     */
54
    const MAX_HEADER_LIST_SIZE = 0x06;
55
56
    /**
57
     * SettingsFrame constructor.
58
     *
59
     * @param array $options
60
     * @throws InvalidFrameException
61
     */
62 9
    public function __construct(array $options = []) // array $settings = [], ... $args)
63
    {
64 9
        parent::__construct($options);
65
66 8
        $options['settings'] = $options['settings'] ?? [];
67
68 8
        if ($options['settings'] && $this->flags->hasFlag(Flag::ACK)) {
69 1
            throw new InvalidFrameException('Settings must be empty if ACK flag is set.');
70
        }
71
72 7
        $this->settings = $options['settings'];
73 7
    }
74
75
    /**
76
     * @return string
77
     */
78 1
    public function serializeBody(): string
79
    {
80 1
        $settings = [];
81 1
        foreach ($this->settings as $setting => $value) {
82 1
            $settings[] = pack('nN', $setting & 0xFF, $value);
83
        }
84
85 1
        return implode('', $settings);
86
    }
87
88
    /**
89
     * Given the body of a frame, parses it into frame data. This populates
90
     * the non-header parts of the frame: that is, it does not populate the
91
     * stream ID or flags.
92
     *
93
     *
94
     * @param string $data
95
     * @throws InvalidFrameException
96
     * @return void
97
     */
98 2
    public function parseBody(string $data)
99
    {
100 2
        foreach (range(0, strlen($data) - 1, 6) as $i) {
101 2 View Code Duplication
            if (!$unpack = @unpack('nname/Nvalue', substr($data, $i, $i + 6))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102 1
                throw new InvalidFrameException('Invalid SETTINGS body');
103
            }
104
105 2
            $name = $unpack['name'];
106 2
            $value = $unpack['value'];
107 2
            $this->settings[$name] = $value;
108
        }
109
110 1
        $this->body_len = strlen($data);
111 1
    }
112
113
    /**
114
     * @return array|mixed
115
     */
116 3
    public function getSettings()
117
    {
118 3
        return $this->settings;
119
    }
120
121
    /**
122
     * @param array|mixed $settings
123
     * @return SettingsFrame
124
     */
125 1
    public function setSettings($settings)
126
    {
127 1
        $this->settings = $settings;
128 1
        return $this;
129
    }
130
}
131