Completed
Branch master (1d1574)
by Evgenij
18:38
created

MarkerFramePicker::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 3
crap 1
1
<?php
2
/**
3
 * Async sockets
4
 *
5
 * @copyright Copyright (c) 2015-2016, Efimov Evgenij <[email protected]>
6
 *
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
namespace AsyncSockets\Frame;
11
12
/**
13
 * Class MarkerFramePicker
14
 */
15
class MarkerFramePicker extends AbstractFramePicker
16
{
17
    /**
18
     * Frame start byte sequence or null
19
     *
20
     * @var string|null
21
     */
22
    private $startMarker;
23
24
    /**
25
     * Frame end marker
26
     *
27
     * @var string
28
     */
29
    private $endMarker;
30
31
    /**
32
     * Offset to search for end marker during data handling
33
     *
34
     * @var int
35
     */
36
    private $startPos;
37
38
    /**
39
     * bool
40
     *
41
     * @var bool
42
     */
43
    private $isCaseSensitive;
44
45
    /**
46
     * MarkerFramePicker constructor.
47
     *
48
     * @param null|string $startMarker Start marker
49
     * @param string      $endMarker End marker
50
     * @param bool        $isCaseSensitive True, if case is important
51
     */
52 30
    public function __construct($startMarker, $endMarker, $isCaseSensitive = true)
53
    {
54 30
        parent::__construct();
55 30
        $this->startMarker     = $startMarker;
56 30
        $this->endMarker       = $endMarker;
57 30
        $this->isCaseSensitive = $isCaseSensitive;
58 30
    }
59
60
    /**
61
     * Find start of data in frame
62
     *
63
     * @param string $buffer Collected data for frame
64
     *
65
     * @return bool True if start of frame is found
66
     */
67 29
    protected function resolveStartOfFrame($buffer)
68
    {
69 29
        if ($this->startPos !== null) {
70 7
            return true;
71
        }
72
73 29
        if ($this->startMarker === null) {
74 4
            $this->startPos = 0;
75 4
            return true;
76
        }
77
78 25
        $pos = $this->findMarker($buffer, $this->startMarker);
79 25
        if ($pos !== false) {
80 19
            $this->startPos = $pos;
81 19
            return true;
82
        }
83
84 8
        return false;
85
    }
86
87
    /** {@inheritdoc} */
88 29
    protected function doHandleData($chunk, $remoteAddress, &$buffer)
89
    {
90 29
        $buffer .= $chunk;
91 29
        if (!$this->resolveStartOfFrame($buffer)) {
92 8
            return '';
93
        }
94
95 23
        $pos = $this->findMarker($buffer, $this->endMarker, $this->startPos + strlen($this->startMarker));
96 23
        if ($pos === false) {
97 12
            return '';
98
        }
99
100 17
        $this->setFinished(true);
101 17
        $result = substr($buffer, $pos + strlen($this->endMarker));
102 17
        $buffer = substr($buffer, $this->startPos, $pos + strlen($this->endMarker) - $this->startPos);
103 17
        return $result !== false ? $result : '';
104
    }
105
106
    /** {@inheritdoc} */
107 29
    protected function doCreateFrame($buffer, $remoteAddress)
108
    {
109 29
        if ($this->isEof()) {
110 17
            return new Frame($buffer, $remoteAddress);
111
        }
112
113 12
        $data = $this->startPos === null ? '' : substr($buffer, $this->startPos);
114 12
        return new Frame($data, $remoteAddress);
115
    }
116
117
    /**
118
     * Performs strpos or stripos according to case sensibility
119
     *
120
     * @param string $haystack Where find text
121
     * @param string $needle What to find
122
     * @param int    $offset Start offset in $haystack
123
     *
124
     * @return bool|int
125
     */
126 29
    protected function findMarker($haystack, $needle, $offset = 0)
127
    {
128 29
        return $this->isCaseSensitive ?
129 29
            strpos($haystack, $needle, $offset) :
130 29
            stripos($haystack, $needle, $offset);
131
    }
132
}
133