• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prooph / event-store-client / 9555551525

17 Jun 2024 10:16PM UTC coverage: 70.262% (-1.1%) from 71.395%
9555551525

push

github

prolic
update coveralls repo token

3466 of 4933 relevant lines covered (70.26%)

67.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.65
/src/SystemData/TcpPackage.php
1
<?php
2

3
/**
4
 * This file is part of `prooph/event-store-client`.
5
 * (c) 2018-2024 Alexander Miertsch <kontakt@codeliner.ws>
6
 * (c) 2018-2024 Sascha-Oliver Prolic <saschaprolic@googlemail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Prooph\EventStoreClient\SystemData;
15

16
use Prooph\EventStore\Exception\InvalidArgumentException;
17

18
/**
19
 * @internal
20
 *
21
 * @psalm-immutable
22
 */
23
class TcpPackage
24
{
25
    public const CommandOffset = 0;
26

27
    public const FlagOffset = self::CommandOffset + 1;
28

29
    public const CorrelationOffset = self::FlagOffset + 1;
30

31
    public const AuthOffset = self::CorrelationOffset + 16;
32

33
    public const MandatorySize = self::AuthOffset;
34

35
    public const DataOffset = 4;
36

37
    private readonly TcpCommand $command;
38

39
    private readonly TcpFlags $flags;
40

41
    private readonly string $correlationId;
42

43
    private readonly string $data;
44

45
    private readonly ?string $login;
46

47
    private readonly ?string $password;
48

49
    /**
50
     * @psalm-pure
51
     */
52
    public static function fromRawData(string $bytes): TcpPackage
53
    {
54
        list('m' => $messageLength, 'c' => $command, 'f' => $flags) = \unpack('Vm/Cc/Cf/', $bytes, self::CommandOffset);
403✔
55

56
        if ($messageLength < self::MandatorySize) {
403✔
57
            throw new InvalidArgumentException('RawData too short, length: ' . $messageLength);
×
58
        }
59

60
        $headerSize = self::MandatorySize;
403✔
61
        $command = TcpCommand::from($command);
403✔
62
        $flags = TcpFlags::from($flags);
403✔
63
        $login = null;
403✔
64
        $pass = null;
403✔
65

66
        list('c' => $correlationId) = \unpack('H32c', $bytes, self::DataOffset + self::CorrelationOffset);
403✔
67

68
        if ($flags === TcpFlags::Authenticated) {
403✔
69
            list('l' => $loginLen) = \unpack('Cl/', $bytes, self::AuthOffset + self::DataOffset);
2✔
70
            list('l' => $login) = \unpack('a' . $loginLen . 'l/', $bytes, self::AuthOffset + self::DataOffset + 1);
2✔
71

72
            list('p' => $passLen) = \unpack('Cp/', $bytes, self::AuthOffset + self::DataOffset + 1 + $loginLen);
2✔
73
            list('p' => $pass) = \unpack('a' . $passLen . 'p/', $bytes, self::AuthOffset + self::DataOffset + 2 + $loginLen);
2✔
74

75
            $headerSize += 1 + $loginLen + 1 + $passLen;
2✔
76
        }
77

78
        list('d' => $data) = \unpack('a' . ($messageLength - $headerSize) . 'd/', $bytes, self::DataOffset + $headerSize);
403✔
79

80
        return new self($command, $flags, $correlationId, $data, $login, $pass);
403✔
81
    }
82

83
    public function __construct(
84
        TcpCommand $command,
85
        TcpFlags $flags,
86
        string $correlationId,
87
        string $data = '',
88
        ?string $login = null,
89
        ?string $password = null
90
    ) {
91
        if ($flags === TcpFlags::Authenticated) {
415✔
92
            if (null === $login) {
244✔
93
                throw new InvalidArgumentException('Login not provided for authorized TcpPackage');
1✔
94
            }
95

96
            if (null === $password) {
243✔
97
                throw new InvalidArgumentException('Password not provided for authorized TcpPackage');
1✔
98
            }
99
        } else {
100
            if (null !== $login) {
409✔
101
                throw new InvalidArgumentException('Login provided for non-authorized TcpPackage');
1✔
102
            }
103

104
            if (null !== $password) {
408✔
105
                throw new InvalidArgumentException('Password provided for non-authorized TcpPackage');
1✔
106
            }
107
        }
108

109
        $this->command = $command;
411✔
110
        $this->flags = $flags;
411✔
111
        $this->correlationId = $correlationId;
411✔
112
        $this->data = $data;
411✔
113
        $this->login = $login;
411✔
114
        $this->password = $password;
411✔
115
    }
116

117
    public function asBytes(): string
118
    {
119
        $dataLen = \strlen($this->data);
407✔
120
        $headerSize = self::MandatorySize;
407✔
121
        $messageLen = $headerSize + $dataLen;
407✔
122

123
        /** @psalm-suppress ImpureMethodCall */
124
        if ($this->flags === TcpFlags::Authenticated) {
407✔
125
            $loginLen = \strlen((string) $this->login);
242✔
126
            $passLen = \strlen((string) $this->password);
242✔
127

128
            if ($loginLen > 255) {
242✔
129
                throw new InvalidArgumentException(\sprintf(
1✔
130
                    'Login length should be less then 256 bytes (but is %d)',
1✔
131
                    $loginLen
1✔
132
                ));
1✔
133
            }
134

135
            if ($passLen > 255) {
241✔
136
                throw new InvalidArgumentException(\sprintf(
1✔
137
                    'Password length should be less then 256 bytes (but is %d)',
1✔
138
                    $passLen
1✔
139
                ));
1✔
140
            }
141

142
            return \pack(
240✔
143
                'VCCH32Ca' . $loginLen . 'Ca' . $passLen . 'a' . $dataLen,
240✔
144
                $messageLen + 2 + $loginLen + $passLen,
240✔
145
                $this->command->value,
240✔
146
                TcpFlags::Authenticated->value,
240✔
147
                $this->correlationId,
240✔
148
                $loginLen,
240✔
149
                $this->login,
240✔
150
                $passLen,
240✔
151
                $this->password,
240✔
152
                $this->data
240✔
153
            );
240✔
154
        }
155

156
        return \pack(
403✔
157
            'VCCH32a' . $dataLen,
403✔
158
            $messageLen,
403✔
159
            $this->command->value,
403✔
160
            TcpFlags::None->value,
403✔
161
            $this->correlationId,
403✔
162
            $this->data
403✔
163
        );
403✔
164
    }
165

166
    public function command(): TcpCommand
167
    {
168
        return $this->command;
403✔
169
    }
170

171
    public function flags(): TcpFlags
172
    {
173
        return $this->flags;
4✔
174
    }
175

176
    public function correlationId(): string
177
    {
178
        return $this->correlationId;
403✔
179
    }
180

181
    public function data(): string
182
    {
183
        return $this->data;
400✔
184
    }
185

186
    public function login(): ?string
187
    {
188
        return $this->login;
4✔
189
    }
190

191
    public function password(): ?string
192
    {
193
        return $this->password;
4✔
194
    }
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc