1: <?php
2:
3: 4: 5: 6: 7: 8: 9:
10:
11: 12: 13: 14: 15: 16:
17: class Swift_StreamFilters_ByteArrayReplacementFilter implements Swift_StreamFilter
18: {
19:
20: private $_search;
21:
22:
23: private $_replace;
24:
25:
26: private $_index;
27:
28:
29: private $_tree = array();
30:
31:
32: private $_treeMaxLen = 0;
33:
34: private $_repSize;
35:
36: 37: 38: 39: 40:
41: public function __construct($search, $replace)
42: {
43: $this->_search = $search;
44: $this->_index = array();
45: $this->_tree = array();
46: $this->_replace = array();
47: $this->_repSize = array();
48:
49: $tree = null;
50: $i = null;
51: $last_size = $size = 0;
52: foreach ($search as $i => $search_element) {
53: if ($tree !== null) {
54: $tree[-1] = min (count($replace) - 1, $i - 1);
55: $tree[-2] = $last_size;
56: }
57: $tree = &$this->_tree;
58: if (is_array ($search_element)) {
59: foreach ($search_element as $k => $char) {
60: $this->_index[$char] = true;
61: if (!isset($tree[$char])) {
62: $tree[$char] = array();
63: }
64: $tree = &$tree[$char];
65: }
66: $last_size = $k+1;
67: $size = max($size, $last_size);
68: } else {
69: $last_size = 1;
70: if (!isset($tree[$search_element])) {
71: $tree[$search_element] = array();
72: }
73: $tree = &$tree[$search_element];
74: $size = max($last_size, $size);
75: $this->_index[$search_element] = true;
76: }
77: }
78: if ($i !== null) {
79: $tree[-1] = min (count ($replace) - 1, $i);
80: $tree[-2] = $last_size;
81: $this->_treeMaxLen = $size;
82: }
83: foreach ($replace as $rep) {
84: if (!is_array($rep)) {
85: $rep = array ($rep);
86: }
87: $this->_replace[] = $rep;
88: }
89: for ($i = count($this->_replace) - 1; $i >= 0; --$i) {
90: $this->_replace[$i] = $rep = $this->filter($this->_replace[$i], $i);
91: $this->_repSize[$i] = count($rep);
92: }
93: }
94:
95: 96: 97: 98: 99:
100: public function shouldBuffer($buffer)
101: {
102: $endOfBuffer = end($buffer);
103:
104: return isset ($this->_index[$endOfBuffer]);
105: }
106:
107: 108: 109: 110: 111:
112: public function filter($buffer, $_minReplaces = -1)
113: {
114: if ($this->_treeMaxLen == 0) {
115: return $buffer;
116: }
117:
118: $newBuffer = array();
119: $buf_size = count($buffer);
120: for ($i = 0; $i < $buf_size; ++$i) {
121: $search_pos = $this->_tree;
122: $last_found = PHP_INT_MAX;
123:
124: for ($j = 0; $j <= $this->_treeMaxLen; ++$j) {
125:
126: if (isset ($buffer [$p = $i + $j]) && isset($search_pos[$buffer[$p]])) {
127: $search_pos = $search_pos[$buffer[$p]];
128:
129: if (isset($search_pos[- 1]) && $search_pos[-1] < $last_found
130: && $search_pos[-1] > $_minReplaces)
131: {
132: $last_found = $search_pos[-1];
133: $last_size = $search_pos[-2];
134: }
135: }
136:
137: elseif ($last_found !== PHP_INT_MAX) {
138:
139: $rep_size = $this->_repSize[$last_found];
140: for ($j = 0; $j < $rep_size; ++$j) {
141: $newBuffer[] = $this->_replace[$last_found][$j];
142: }
143:
144: $i += $last_size - 1;
145:
146: if ($i >= $buf_size) {
147: $newBuffer[] = $buffer[$i];
148: }
149:
150:
151: continue 2;
152: } else {
153:
154: break;
155: }
156: }
157:
158: $newBuffer[] = $buffer[$i];
159: }
160:
161: return $newBuffer;
162: }
163: }
164: