TYPO3  7.6
ByteArrayReplacementFilter.php
Go to the documentation of this file.
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 
19 {
21  private $_search;
22 
24  private $_replace;
25 
27  private $_index;
28 
30  private $_tree = array();
31 
33  private $_treeMaxLen = 0;
34 
35  private $_repSize;
36 
43  public function __construct($search, $replace)
44  {
45  $this->_search = $search;
46  $this->_index = array();
47  $this->_tree = array();
48  $this->_replace = array();
49  $this->_repSize = array();
50 
51  $tree = null;
52  $i = null;
53  $last_size = $size = 0;
54  foreach ($search as $i => $search_element) {
55  if ($tree !== null) {
56  $tree[-1] = min(count($replace) - 1, $i - 1);
57  $tree[-2] = $last_size;
58  }
59  $tree = &$this->_tree;
60  if (is_array($search_element)) {
61  foreach ($search_element as $k => $char) {
62  $this->_index[$char] = true;
63  if (!isset($tree[$char])) {
64  $tree[$char] = array();
65  }
66  $tree = &$tree[$char];
67  }
68  $last_size = $k + 1;
69  $size = max($size, $last_size);
70  } else {
71  $last_size = 1;
72  if (!isset($tree[$search_element])) {
73  $tree[$search_element] = array();
74  }
75  $tree = &$tree[$search_element];
76  $size = max($last_size, $size);
77  $this->_index[$search_element] = true;
78  }
79  }
80  if ($i !== null) {
81  $tree[-1] = min(count($replace) - 1, $i);
82  $tree[-2] = $last_size;
83  $this->_treeMaxLen = $size;
84  }
85  foreach ($replace as $rep) {
86  if (!is_array($rep)) {
87  $rep = array($rep);
88  }
89  $this->_replace[] = $rep;
90  }
91  for ($i = count($this->_replace) - 1; $i >= 0; --$i) {
92  $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i);
93  $this->_repSize[$i] = count($rep);
94  }
95  }
96 
104  public function shouldBuffer($buffer)
105  {
106  $endOfBuffer = end($buffer);
107 
108  return isset($this->_index[$endOfBuffer]);
109  }
110 
119  public function filter($buffer, $_minReplaces = -1)
120  {
121  if ($this->_treeMaxLen == 0) {
122  return $buffer;
123  }
124 
125  $newBuffer = array();
126  $buf_size = count($buffer);
127  for ($i = 0; $i < $buf_size; ++$i) {
128  $search_pos = $this->_tree;
129  $last_found = PHP_INT_MAX;
130  // We try to find if the next byte is part of a search pattern
131  for ($j = 0; $j <= $this->_treeMaxLen; ++$j) {
132  // We have a new byte for a search pattern
133  if (isset($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) {
134  $search_pos = $search_pos[$buffer[$p]];
135  // We have a complete pattern, save, in case we don't find a better match later
136  if (isset($search_pos[-1]) && $search_pos[-1] < $last_found
137  && $search_pos[-1] > $_minReplaces) {
138  $last_found = $search_pos[-1];
139  $last_size = $search_pos[-2];
140  }
141  }
142  // We got a complete pattern
143  elseif ($last_found !== PHP_INT_MAX) {
144  // Adding replacement datas to output buffer
145  $rep_size = $this->_repSize[$last_found];
146  for ($j = 0; $j < $rep_size; ++$j) {
147  $newBuffer[] = $this->_replace[$last_found][$j];
148  }
149  // We Move cursor forward
150  $i += $last_size - 1;
151  // Edge Case, last position in buffer
152  if ($i >= $buf_size) {
153  $newBuffer[] = $buffer[$i];
154  }
155 
156  // We start the next loop
157  continue 2;
158  } else {
159  // this byte is not in a pattern and we haven't found another pattern
160  break;
161  }
162  }
163  // Normal byte, move it to output buffer
164  $newBuffer[] = $buffer[$i];
165  }
166 
167  return $newBuffer;
168  }
169 }