1: <?php
2:
3: /*
4: * This file is part of SwiftMailer.
5: * (c) 2004-2009 Chris Corbyn
6: *
7: * For the full copyright and license information, please view the LICENSE
8: * file that was distributed with this source code.
9: */
10:
11: /**
12: * Provides the base functionality for an InputStream supporting filters.
13: * @package Swift
14: * @subpackage ByteStream
15: * @author Chris Corbyn
16: */
17: abstract class Swift_ByteStream_AbstractFilterableInputStream implements Swift_InputByteStream, Swift_Filterable
18: {
19: /** Write sequence */
20: protected $_sequence = 0;
21:
22: /** StreamFilters */
23: private $_filters = array();
24:
25: /** A buffer for writing */
26: private $_writeBuffer = '';
27:
28: /** Bound streams */
29: private $_mirrors = array();
30:
31: /**
32: * Commit the given bytes to the storage medium immediately.
33: * @param string $bytes
34: * @access protected
35: */
36: abstract protected function _commit($bytes);
37:
38: /**
39: * Flush any buffers/content with immediate effect.
40: * @access protected
41: */
42: abstract protected function _flush();
43:
44: /**
45: * Add a StreamFilter to this InputByteStream.
46: * @param Swift_StreamFilter $filter
47: * @param string $key
48: */
49: public function addFilter(Swift_StreamFilter $filter, $key)
50: {
51: $this->_filters[$key] = $filter;
52: }
53:
54: /**
55: * Remove an already present StreamFilter based on its $key.
56: * @param string $key
57: */
58: public function removeFilter($key)
59: {
60: unset($this->_filters[$key]);
61: }
62:
63: /**
64: * Writes $bytes to the end of the stream.
65: * @param string $bytes
66: * @throws Swift_IoException
67: */
68: public function write($bytes)
69: {
70: $this->_writeBuffer .= $bytes;
71: foreach ($this->_filters as $filter) {
72: if ($filter->shouldBuffer($this->_writeBuffer)) {
73: return;
74: }
75: }
76: $this->_doWrite($this->_writeBuffer);
77:
78: return ++$this->_sequence;
79: }
80:
81: /**
82: * For any bytes that are currently buffered inside the stream, force them
83: * off the buffer.
84: *
85: * @throws Swift_IoException
86: */
87: public function commit()
88: {
89: $this->_doWrite($this->_writeBuffer);
90: }
91:
92: /**
93: * Attach $is to this stream.
94: * The stream acts as an observer, receiving all data that is written.
95: * All {@link write()} and {@link flushBuffers()} operations will be mirrored.
96: *
97: * @param Swift_InputByteStream $is
98: */
99: public function bind(Swift_InputByteStream $is)
100: {
101: $this->_mirrors[] = $is;
102: }
103:
104: /**
105: * Remove an already bound stream.
106: * If $is is not bound, no errors will be raised.
107: * If the stream currently has any buffered data it will be written to $is
108: * before unbinding occurs.
109: *
110: * @param Swift_InputByteStream $is
111: */
112: public function unbind(Swift_InputByteStream $is)
113: {
114: foreach ($this->_mirrors as $k => $stream) {
115: if ($is === $stream) {
116: if ($this->_writeBuffer !== '') {
117: $stream->write($this->_filter($this->_writeBuffer));
118: }
119: unset($this->_mirrors[$k]);
120: }
121: }
122: }
123:
124: /**
125: * Flush the contents of the stream (empty it) and set the internal pointer
126: * to the beginning.
127: * @throws Swift_IoException
128: */
129: public function flushBuffers()
130: {
131: if ($this->_writeBuffer !== '') {
132: $this->_doWrite($this->_writeBuffer);
133: }
134: $this->_flush();
135:
136: foreach ($this->_mirrors as $stream) {
137: $stream->flushBuffers();
138: }
139: }
140:
141: // -- Private methods
142:
143: /** Run $bytes through all filters */
144: private function _filter($bytes)
145: {
146: foreach ($this->_filters as $filter) {
147: $bytes = $filter->filter($bytes);
148: }
149:
150: return $bytes;
151: }
152:
153: /** Just write the bytes to the stream */
154: private function _doWrite($bytes)
155: {
156: $this->_commit($this->_filter($bytes));
157:
158: foreach ($this->_mirrors as $stream) {
159: $stream->write($bytes);
160: }
161:
162: $this->_writeBuffer = '';
163: }
164: }
165: