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

azjezz / psl / 23100354439

15 Mar 2026 01:10AM UTC coverage: 95.628% (-2.8%) from 98.421%
23100354439

Pull #629

github

azjezz
feat(encoding): introduce streaming IO handles for Base64, QuotedPrintable, and Hex

Signed-off-by: azjezz <azjezz@protonmail.com>
Pull Request #629: feat(encoding): introduce streaming IO handles for Base64, QuotedPrintable, and Hex

479 of 797 new or added lines in 13 files covered. (60.1%)

2 existing lines in 1 file now uncovered.

10455 of 10933 relevant lines covered (95.63%)

32.65 hits per line

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

95.24
/src/Psl/Encoding/QuotedPrintable/EncodingWriteHandle.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Psl\Encoding\QuotedPrintable;
6

7
use Psl\Async\CancellationTokenInterface;
8
use Psl\Async\NullCancellationToken;
9
use Psl\IO;
10

11
use function str_ends_with;
12
use function strlen;
13
use function strpos;
14
use function substr;
15

16
/**
17
 * A write handle that accepts raw text and writes quoted-printable encoded output to an inner handle.
18
 *
19
 * Buffers input until complete lines (terminated by \n) are available,
20
 * encodes each line via {@see encode_line()}, and writes to the inner handle with "\r\n" line endings.
21
 */
22
final class EncodingWriteHandle implements IO\WriteHandleInterface
23
{
24
    use IO\WriteHandleConvenienceMethodsTrait;
25

26
    private string $buffer = '';
27
    private bool $firstLine = true;
28

29
    public function __construct(
30
        private readonly IO\WriteHandleInterface $handle,
31
    ) {}
4✔
32

33
    public function tryWrite(string $bytes): int
34
    {
35
        $length = strlen($bytes);
4✔
36
        $this->buffer .= $bytes;
4✔
37
        $this->drainCompleteLines();
4✔
38
        return $length;
4✔
39
    }
40

41
    public function write(string $bytes, CancellationTokenInterface $cancellation = new NullCancellationToken()): int
42
    {
43
        return $this->tryWrite($bytes);
4✔
44
    }
45

46
    /**
47
     * Flush any remaining buffered data through the encoder to the inner handle.
48
     */
49
    public function flush(): void
50
    {
51
        if ($this->buffer !== '') {
4✔
52
            $line = str_ends_with($this->buffer, "\r") ? substr($this->buffer, 0, -1) : $this->buffer;
4✔
53

54
            if (!$this->firstLine) {
4✔
55
                $this->handle->writeAll("\r\n");
3✔
56
            }
57

58
            $this->handle->writeAll(encode_line($line));
4✔
59
            $this->buffer = '';
4✔
60
            $this->firstLine = false;
4✔
61
        }
62
    }
63

64
    private function drainCompleteLines(): void
65
    {
66
        while (false !== ($pos = strpos($this->buffer, "\n"))) {
4✔
67
            $line = substr($this->buffer, 0, $pos);
3✔
68
            $line = str_ends_with($line, "\r") ? substr($line, 0, -1) : $line;
3✔
69
            $this->buffer = substr($this->buffer, $pos + 1);
3✔
70

71
            if (!$this->firstLine) {
3✔
NEW
72
                $this->handle->writeAll("\r\n");
×
73
            }
74

75
            $this->handle->writeAll(encode_line($line));
3✔
76
            $this->firstLine = false;
3✔
77
        }
78
    }
79
}
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

© 2026 Coveralls, Inc