|
TYPO3 API
SVNRelease
|
00001 <?php 00002 00003 /* 00004 * This file is part of SwiftMailer. 00005 * (c) 2004-2009 Chris Corbyn 00006 * 00007 * For the full copyright and license information, please view the LICENSE 00008 * file that was distributed with this source code. 00009 */ 00010 00011 //@require 'Swift/StreamFilter.php'; 00012 00013 /** 00014 * Processes bytes as they pass through a buffer and replaces sequences in it. 00015 * This stream filter deals with Byte arrays rather than simple strings. 00016 * @package Swift 00017 * @author Chris Corbyn 00018 */ 00019 class Swift_StreamFilters_ByteArrayReplacementFilter 00020 implements Swift_StreamFilter 00021 { 00022 00023 /** The needle(s) to search for */ 00024 private $_search; 00025 00026 /** The replacement(s) to make */ 00027 private $_replace; 00028 00029 /** The Index for searching */ 00030 private $_index; 00031 00032 /** The Search Tree */ 00033 private $_tree = array(); 00034 00035 /** Gives the size of the largest search */ 00036 private $_treeMaxLen = 0; 00037 00038 private $_repSize; 00039 00040 /** 00041 * Create a new ByteArrayReplacementFilter with $search and $replace. 00042 * @param array $search 00043 * @param array $replace 00044 */ 00045 public function __construct($search, $replace) 00046 { 00047 $this->_search = $search; 00048 $this->_index = array(); 00049 $this->_tree = array(); 00050 $this->_replace = array(); 00051 $this->_repSize = array(); 00052 00053 $tree = null; 00054 $i = null; 00055 $last_size = $size = 0; 00056 foreach ($search as $i => $search_element) 00057 { 00058 if ($tree !== null) 00059 { 00060 $tree[-1] = min (count($replace) - 1, $i - 1); 00061 $tree[-2] = $last_size; 00062 } 00063 $tree = &$this->_tree; 00064 if (is_array ($search_element)) 00065 { 00066 foreach ($search_element as $k => $char) 00067 { 00068 $this->_index[$char] = true; 00069 if (!isset($tree[$char])) 00070 { 00071 $tree[$char] = array(); 00072 } 00073 $tree = &$tree[$char]; 00074 } 00075 $last_size = $k+1; 00076 $size = max($size, $last_size); 00077 } 00078 else 00079 { 00080 $last_size = 1; 00081 if (!isset($tree[$search_element])) 00082 { 00083 $tree[$search_element] = array(); 00084 } 00085 $tree = &$tree[$search_element]; 00086 $size = max($last_size, $size); 00087 $this->_index[$search_element] = true; 00088 } 00089 } 00090 if ($i !== null) 00091 { 00092 $tree[-1] = min (count ($replace) - 1, $i); 00093 $tree[-2] = $last_size; 00094 $this->_treeMaxLen = $size; 00095 } 00096 foreach ($replace as $rep) 00097 { 00098 if (!is_array($rep)) 00099 { 00100 $rep = array ($rep); 00101 } 00102 $this->_replace[] = $rep; 00103 } 00104 for ($i = count($this->_replace) - 1; $i >= 0; --$i) 00105 { 00106 $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i); 00107 $this->_repSize[$i] = count($rep); 00108 } 00109 } 00110 00111 /** 00112 * Returns true if based on the buffer passed more bytes should be buffered. 00113 * @param array $buffer 00114 * @return boolean 00115 */ 00116 public function shouldBuffer($buffer) 00117 { 00118 $endOfBuffer = end($buffer); 00119 return isset ($this->_index[$endOfBuffer]); 00120 } 00121 00122 /** 00123 * Perform the actual replacements on $buffer and return the result. 00124 * @param array $buffer 00125 * @return array 00126 */ 00127 public function filter($buffer, $_minReplaces = -1) 00128 { 00129 if ($this->_treeMaxLen == 0) 00130 { 00131 return $buffer; 00132 } 00133 00134 $newBuffer = array(); 00135 $buf_size = count($buffer); 00136 for ($i = 0; $i < $buf_size; ++$i) 00137 { 00138 $search_pos = $this->_tree; 00139 $last_found = PHP_INT_MAX; 00140 // We try to find if the next byte is part of a search pattern 00141 for ($j = 0; $j <= $this->_treeMaxLen; ++$j) 00142 { 00143 // We have a new byte for a search pattern 00144 if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) 00145 { 00146 $search_pos = $search_pos[$buffer[$p]]; 00147 // We have a complete pattern, save, in case we don't find a better match later 00148 if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found 00149 && $search_pos[-1] > $_minReplaces) 00150 { 00151 $last_found = $search_pos[-1]; 00152 $last_size = $search_pos[-2]; 00153 } 00154 } 00155 // We got a complete pattern 00156 elseif ($last_found !== PHP_INT_MAX) 00157 { 00158 // Adding replacement datas to output buffer 00159 $rep_size = $this->_repSize[$last_found]; 00160 for ($j = 0; $j < $rep_size; ++$j) 00161 { 00162 $newBuffer[] = $this->_replace[$last_found][$j]; 00163 } 00164 // We Move cursor forward 00165 $i += $last_size - 1; 00166 // Edge Case, last position in buffer 00167 if ($i >= $buf_size) 00168 { 00169 $newBuffer[] = $buffer[$i]; 00170 } 00171 00172 // We start the next loop 00173 continue 2; 00174 } 00175 else 00176 { 00177 // this byte is not in a pattern and we haven't found another pattern 00178 break; 00179 } 00180 } 00181 // Normal byte, move it to output buffer 00182 $newBuffer[] = $buffer[$i]; 00183 } 00184 00185 return $newBuffer; 00186 } 00187 00188 }
1.8.0