Completed
Push — master ( 0bb29a...06c72e )
by Peter
03:57
created

OutputStream::push()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 20
ccs 12
cts 12
cp 1
rs 9.2
c 1
b 0
f 0
cc 4
eloc 11
nc 4
nop 1
crap 4
1
<?php
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Component\Sitemap\Stream;
11
12
use GpsLab\Component\Sitemap\Render\SitemapRender;
13
use GpsLab\Component\Sitemap\Stream\Exception\LinksOverflowException;
14
use GpsLab\Component\Sitemap\Stream\Exception\SizeOverflowException;
15
use GpsLab\Component\Sitemap\Stream\Exception\StreamStateException;
16
use GpsLab\Component\Sitemap\Stream\State\StreamState;
17
use GpsLab\Component\Sitemap\Url\Url;
18
19
class OutputStream implements Stream
20
{
21
    const LINKS_LIMIT = 50000;
22
23
    const BYTE_LIMIT = 52428800; // 50 Mb
24
25
    /**
26
     * @var SitemapRender
27
     */
28
    private $render;
29
30
    /**
31
     * @var StreamState
32
     */
33
    private $state;
34
35
    /**
36
     * @var int
37
     */
38
    private $counter = 0;
39
40
    /**
41
     * @var int
42
     */
43
    private $used_bytes = 0;
44
45
    /**
46
     * @var string
47
     */
48
    private $end_string = '';
49
50
    /**
51
     * @param SitemapRender $render
52
     */
53 9
    public function __construct(SitemapRender $render)
54
    {
55 9
        $this->render = $render;
56 9
        $this->state = new StreamState();
57 9
    }
58
59 7
    public function open()
60
    {
61 7
        $this->state->open();
62 7
        $this->send($this->render->start());
63
        // render end string only once
64 7
        $this->end_string = $this->render->end();
65 7
    }
66
67 8
    public function close()
68
    {
69 8
        $this->state->close();
70 7
        $this->send($this->end_string);
71 7
    }
72
73
    /**
74
     * @param Url $url
75
     */
76 5
    public function push(Url $url)
77
    {
78 5
        if (!$this->state->isReady()) {
79 2
            throw StreamStateException::notReady();
80
        }
81
82 3
        if ($this->counter >= self::LINKS_LIMIT) {
83 1
            throw LinksOverflowException::withLimit(self::LINKS_LIMIT);
84
        }
85
86 3
        $render_url = $this->render->url($url);
87 3
        $expected_bytes = $this->used_bytes + strlen($render_url) + strlen($this->end_string);
88
89 3
        if ($expected_bytes > self::BYTE_LIMIT) {
90 1
            throw SizeOverflowException::withLimit(self::BYTE_LIMIT);
91
        }
92
93 3
        $this->send($render_url);
94 3
        ++$this->counter;
95 3
    }
96
97
    /**
98
     * @return int
99
     */
100 1
    public function count()
101
    {
102 1
        return $this->counter;
103
    }
104
105
    /**
106
     * @param string $string
107
     */
108 7
    private function send($string)
109
    {
110 7
        echo $string;
111 7
        flush();
112 7
        $this->used_bytes += strlen($string);
113 7
    }
114
}
115