Added feature #15998: Create a new API to send mails based on SwiftMailer to replace...
[Packages/TYPO3.CMS.git] / typo3 / contrib / swiftmailer / classes / Swift / StreamFilters / ByteArrayReplacementFilter.php
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 //@require 'Swift/StreamFilter.php';
12
13 /**
14 * Processes bytes as they pass through a buffer and replaces sequences in it.
15 * This stream filter deals with Byte arrays rather than simple strings.
16 * @package Swift
17 * @author Chris Corbyn
18 */
19 class Swift_StreamFilters_ByteArrayReplacementFilter
20 implements Swift_StreamFilter
21 {
22
23 /** The needle(s) to search for */
24 private $_search;
25
26 /** The replacement(s) to make */
27 private $_replace;
28
29 /** The Index for searching */
30 private $_index;
31
32 /** The Search Tree */
33 private $_tree = array();
34
35 /** Gives the size of the largest search */
36 private $_treeMaxLen = 0;
37
38 private $_repSize;
39
40 /**
41 * Create a new ByteArrayReplacementFilter with $search and $replace.
42 * @param array $search
43 * @param array $replace
44 */
45 public function __construct($search, $replace)
46 {
47 $this->_search = $search;
48 $this->_index = array();
49 $this->_tree = array();
50 $this->_replace = array();
51 $this->_repSize = array();
52
53 $tree = null;
54 $i = null;
55 $last_size = $size = 0;
56 foreach ($search as $i => $search_element)
57 {
58 if ($tree !== null)
59 {
60 $tree[-1] = min (count($replace) - 1, $i - 1);
61 $tree[-2] = $last_size;
62 }
63 $tree = &$this->_tree;
64 if (is_array ($search_element))
65 {
66 foreach ($search_element as $k => $char)
67 {
68 $this->_index[$char] = true;
69 if (!isset($tree[$char]))
70 {
71 $tree[$char] = array();
72 }
73 $tree = &$tree[$char];
74 }
75 $last_size = $k+1;
76 $size = max($size, $last_size);
77 }
78 else
79 {
80 $last_size = 1;
81 if (!isset($tree[$search_element]))
82 {
83 $tree[$search_element] = array();
84 }
85 $tree = &$tree[$search_element];
86 $size = max($last_size, $size);
87 $this->_index[$search_element] = true;
88 }
89 }
90 if ($i !== null)
91 {
92 $tree[-1] = min (count ($replace) - 1, $i);
93 $tree[-2] = $last_size;
94 $this->_treeMaxLen = $size;
95 }
96 foreach ($replace as $rep)
97 {
98 if (!is_array($rep))
99 {
100 $rep = array ($rep);
101 }
102 $this->_replace[] = $rep;
103 }
104 for ($i = count($this->_replace) - 1; $i >= 0; --$i)
105 {
106 $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i);
107 $this->_repSize[$i] = count($rep);
108 }
109 }
110
111 /**
112 * Returns true if based on the buffer passed more bytes should be buffered.
113 * @param array $buffer
114 * @return boolean
115 */
116 public function shouldBuffer($buffer)
117 {
118 $endOfBuffer = end($buffer);
119 return isset ($this->_index[$endOfBuffer]);
120 }
121
122 /**
123 * Perform the actual replacements on $buffer and return the result.
124 * @param array $buffer
125 * @return array
126 */
127 public function filter($buffer, $_minReplaces = -1)
128 {
129 if ($this->_treeMaxLen == 0)
130 {
131 return $buffer;
132 }
133
134 $newBuffer = array();
135 $buf_size = count($buffer);
136 for ($i = 0; $i < $buf_size; ++$i)
137 {
138 $search_pos = $this->_tree;
139 $last_found = PHP_INT_MAX;
140 // We try to find if the next byte is part of a search pattern
141 for ($j = 0; $j <= $this->_treeMaxLen; ++$j)
142 {
143 // We have a new byte for a search pattern
144 if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]]))
145 {
146 $search_pos = $search_pos[$buffer[$p]];
147 // We have a complete pattern, save, in case we don't find a better match later
148 if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found
149 && $search_pos[-1] > $_minReplaces)
150 {
151 $last_found = $search_pos[-1];
152 $last_size = $search_pos[-2];
153 }
154 }
155 // We got a complete pattern
156 elseif ($last_found !== PHP_INT_MAX)
157 {
158 // Adding replacement datas to output buffer
159 $rep_size = $this->_repSize[$last_found];
160 for ($j = 0; $j < $rep_size; ++$j)
161 {
162 $newBuffer[] = $this->_replace[$last_found][$j];
163 }
164 // We Move cursor forward
165 $i += $last_size - 1;
166 // Edge Case, last position in buffer
167 if ($i >= $buf_size)
168 {
169 $newBuffer[] = $buffer[$i];
170 }
171
172 // We start the next loop
173 continue 2;
174 }
175 else
176 {
177 // this byte is not in a pattern and we haven't found another pattern
178 break;
179 }
180 }
181 // Normal byte, move it to output buffer
182 $newBuffer[] = $buffer[$i];
183 }
184
185 return $newBuffer;
186 }
187
188 }