1 <?php
2
3 namespace Http\Message\Encoding;
4
5 use Clue\StreamFilter as Filter;
6 use Http\Message\Decorator\StreamDecorator;
7 use Psr\Http\Message\StreamInterface;
8
9 10 11 12 13
14 abstract class FilteredStream implements StreamInterface
15 {
16 const BUFFER_SIZE = 65536;
17
18 use StreamDecorator;
19
20 21 22
23 protected $readFilterCallback;
24
25 26 27
28 protected $readFilter;
29
30 31 32
33 protected $writeFilterCallback;
34
35 36 37
38 protected $writeFilter;
39
40 41 42 43 44
45 protected $buffer = '';
46
47 48 49 50 51
52 public function __construct(StreamInterface $stream, $readFilterOptions = null, $writeFilterOptions = null)
53 {
54 $this->readFilterCallback = Filter\fun($this->getReadFilter(), $readFilterOptions);
55 $this->writeFilterCallback = Filter\fun($this->getWriteFilter(), $writeFilterOptions);
56 $this->stream = $stream;
57 }
58
59 60 61
62 public function read($length)
63 {
64 if (strlen($this->buffer) >= $length) {
65 $read = substr($this->buffer, 0, $length);
66 $this->buffer = substr($this->buffer, $length);
67
68 return $read;
69 }
70
71 if ($this->stream->eof()) {
72 $buffer = $this->buffer;
73 $this->buffer = '';
74
75 return $buffer;
76 }
77
78 $read = $this->buffer;
79 $this->buffer = '';
80 $this->fill();
81
82 return $read.$this->read($length - strlen($read));
83 }
84
85 86 87
88 public function eof()
89 {
90 return $this->stream->eof() && $this->buffer === '';
91 }
92
93 94 95 96 97 98 99
100 protected function fill()
101 {
102 $readFilterCallback = $this->readFilterCallback;
103 $this->buffer .= $readFilterCallback($this->stream->read(self::BUFFER_SIZE));
104
105 if ($this->stream->eof()) {
106 $this->buffer .= $readFilterCallback();
107 }
108 }
109
110 111 112
113 public function getContents()
114 {
115 $buffer = '';
116
117 while (!$this->eof()) {
118 $buf = $this->read(1048576);
119
120 if ($buf == null) {
121 break;
122 }
123
124 $buffer .= $buf;
125 }
126
127 return $buffer;
128 }
129
130 131 132 133 134
135 abstract public function getReadFilter();
136
137 138 139 140 141
142 abstract public function getWriteFilter();
143 }
144