Passed
Push — master ( 4e34bd...29d761 )
by Alexpts
02:16
created

SplitPackageUdp::splitToChunks()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 10
cp 0
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
declare(strict_types=1);
3
4
namespace PTS\Transport;
5
6
class SplitPackageUdp extends UdpSocket
7
{
8
9
    public const CHUNK_MAGIC = "\x1e\x0f";
10
11
    protected $chunkSize = 8144;
12
13
    public function write(string $message, int $length = null): int
14
    {
15
        $packages = $this->splitToChunks($message);
16
        $bytes = 0;
17
        foreach ($packages as $package) {
18
            $bytes += (int)parent::write($package);
19
        }
20
21
        return $bytes;
22
    }
23
24
    /**
25
     * chunk format:
26
     * Chunked magic bytes - 2 bytes: 0x1e 0x0f
27
     * Message ID - 8 bytes: Must be the same for every chunk of this message. Identifying the whole message and is used to reassemble the chunks later
28
     * Sequence number - 1 byte: The sequence number of this chunk. Starting at 0 and always less than the sequence count
29
     * Sequence count - 1 byte: Total number of chunks this message has
30
     * Message chunk
31
     *
32
     * @param string $buffer
33
     *
34
     * @return array
35
     */
36
    protected function splitToChunks(string $buffer): array
37
    {
38
        $chunks = str_split($buffer, $this->chunkSize);
39
        $count = count($chunks);
40
        $id = $this->generateId();
41
42
        foreach ($chunks as $n => &$chunk) {
43
            $chunk = self::CHUNK_MAGIC . $id . pack('CC', $n, $count) . $chunk;
44
        }
45
46
        return $chunks;
47
    }
48
49
    protected function generateId(): string
50
    {
51
        return substr(md5(uniqid('', true), true), 0, 8);
52
    }
53
}
54