Completed
Push — master ( aab6ae...03b37f )
by Zaahid
04:44
created

UUEncodeStreamFilter::filter()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 23
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 23
rs 6.7272
cc 7
eloc 18
nc 5
nop 4
1
<?php
2
/**
3
 * This file is part of the ZBateson\MailMimeParser project.
4
 *
5
 * @license http://opensource.org/licenses/bsd-license.php BSD
6
 */
7
namespace ZBateson\MailMimeParser;
8
9
use php_user_filter;
10
11
/**
12
 * Stream filter converts uuencoded text to its raw binary.
13
 *
14
 * @author Zaahid Bateson
15
 */
16
class UUEncodeStreamFilter extends php_user_filter
17
{
18
    /**
19
     * Name used when registering with stream_filter_register.
20
     */
21
    const STREAM_FILTER_NAME = 'mailmimeparser-uudecode';
22
    
23
    /**
24
     * @var string Leftovers from the last incomplete line that was parsed, to
25
     *      be prepended to the next line read.
26
     */
27
    private $leftover = '';
28
    
29
    /**
30
     * Returns an array of complete lines (including line endings) from the 
31
     * passed $bucket object.
32
     * 
33
     * If the last line on $bucket is incomplete, it's assigned to
34
     * $this->leftover and prepended to the first element of the first line in
35
     * the next call to getLines.
36
     * 
37
     * @param object $bucket
38
     * @return string[]
39
     */
40
    private function getLines($bucket)
41
    {
42
        $lines = preg_split(
43
            '/([^\r\n]+[\r\n]+)/',
44
            $bucket->data,
45
            -1,
46
            PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
47
        );
48
        if (!empty($this->leftover)) {
49
            $lines[0] = $this->leftover . $lines[0];
50
            $this->leftover = '';
51
        }
52
        $last = end($lines);
53
        if ($last[strlen($last) - 1] !== "\n") {
54
            $this->leftover = array_pop($lines);
55
        }
56
        return $lines;
57
    }
58
    
59
    /**
60
     * Filter implementation converts encoding before returning PSFS_PASS_ON.
61
     * 
62
     * @param resource $in
63
     * @param resource $out
64
     * @param int $consumed
65
     * @param bool $closing
66
     * @return int
67
     */
68
    public function filter($in, $out, &$consumed, $closing)
69
    {
70
        while ($bucket = stream_bucket_make_writeable($in)) {
71
            $lines = $this->getLines($bucket);
72
            $data = '';
73
            foreach ($lines as $line) {
74
                $bytes = strlen($line);
75
                $cur = trim($line);
76
                if (empty($cur) || preg_match('/^begin \d{3} .*$/', $cur)) {
77
                    $consumed += $bytes;
78
                    continue;
79
                } elseif ($cur === '`' || $cur === 'end') {
80
                    $consumed += $bytes;
81
                    break;
82
                }
83
                $consumed += $bytes;
84
                $data .= convert_uudecode($cur);
85
            }
86
            $bucket->data = $data;
87
            stream_bucket_append($out, $bucket);
88
        }
89
        return PSFS_PASS_ON;
90
    }
91
}
92