TYPO3  7.6
ArrayCharacterStream.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 
17 {
19  private static $_charMap;
20 
22  private static $_byteMap;
23 
25  private $_charReader;
26 
29 
31  private $_charset;
32 
34  private $_array = array();
35 
37  private $_array_size = array();
38 
40  private $_offset = 0;
41 
48  public function __construct(Swift_CharacterReaderFactory $factory, $charset)
49  {
50  self::_initializeMaps();
51  $this->setCharacterReaderFactory($factory);
52  $this->setCharacterSet($charset);
53  }
54 
60  public function setCharacterSet($charset)
61  {
62  $this->_charset = $charset;
63  $this->_charReader = null;
64  }
65 
72  {
73  $this->_charReaderFactory = $factory;
74  }
75 
82  {
83  if (!isset($this->_charReader)) {
84  $this->_charReader = $this->_charReaderFactory
85  ->getReaderFor($this->_charset);
86  }
87 
88  $startLength = $this->_charReader->getInitialByteSize();
89  while (false !== $bytes = $os->read($startLength)) {
90  $c = array();
91  for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
92  $c[] = self::$_byteMap[$bytes[$i]];
93  }
94  $size = count($c);
95  $need = $this->_charReader
96  ->validateByteSequence($c, $size);
97  if ($need > 0 &&
98  false !== $bytes = $os->read($need)) {
99  for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
100  $c[] = self::$_byteMap[$bytes[$i]];
101  }
102  }
103  $this->_array[] = $c;
105  }
106  }
107 
114  public function importString($string)
115  {
116  $this->flushContents();
117  $this->write($string);
118  }
119 
128  public function read($length)
129  {
130  if ($this->_offset == $this->_array_size) {
131  return false;
132  }
133 
134  // Don't use array slice
135  $arrays = array();
136  $end = $length + $this->_offset;
137  for ($i = $this->_offset; $i < $end; ++$i) {
138  if (!isset($this->_array[$i])) {
139  break;
140  }
141  $arrays[] = $this->_array[$i];
142  }
143  $this->_offset += $i - $this->_offset; // Limit function calls
144  $chars = false;
145  foreach ($arrays as $array) {
146  $chars .= implode('', array_map('chr', $array));
147  }
148 
149  return $chars;
150  }
151 
160  public function readBytes($length)
161  {
162  if ($this->_offset == $this->_array_size) {
163  return false;
164  }
165  $arrays = array();
166  $end = $length + $this->_offset;
167  for ($i = $this->_offset; $i < $end; ++$i) {
168  if (!isset($this->_array[$i])) {
169  break;
170  }
171  $arrays[] = $this->_array[$i];
172  }
173  $this->_offset += ($i - $this->_offset); // Limit function calls
174 
175  return call_user_func_array('array_merge', $arrays);
176  }
177 
183  public function write($chars)
184  {
185  if (!isset($this->_charReader)) {
186  $this->_charReader = $this->_charReaderFactory->getReaderFor(
187  $this->_charset);
188  }
189 
190  $startLength = $this->_charReader->getInitialByteSize();
191 
192  $fp = fopen('php://memory', 'w+b');
193  fwrite($fp, $chars);
194  unset($chars);
195  fseek($fp, 0, SEEK_SET);
196 
197  $buffer = array(0);
198  $buf_pos = 1;
199  $buf_len = 1;
200  $has_datas = true;
201  do {
202  $bytes = array();
203  // Buffer Filing
204  if ($buf_len - $buf_pos < $startLength) {
205  $buf = array_splice($buffer, $buf_pos);
206  $new = $this->_reloadBuffer($fp, 100);
207  if ($new) {
208  $buffer = array_merge($buf, $new);
209  $buf_len = count($buffer);
210  $buf_pos = 0;
211  } else {
212  $has_datas = false;
213  }
214  }
215  if ($buf_len - $buf_pos > 0) {
216  $size = 0;
217  for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) {
218  ++$size;
219  $bytes[] = $buffer[$buf_pos++];
220  }
221  $need = $this->_charReader->validateByteSequence(
222  $bytes, $size);
223  if ($need > 0) {
224  if ($buf_len - $buf_pos < $need) {
225  $new = $this->_reloadBuffer($fp, $need);
226 
227  if ($new) {
228  $buffer = array_merge($buffer, $new);
229  $buf_len = count($buffer);
230  }
231  }
232  for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) {
233  $bytes[] = $buffer[$buf_pos++];
234  }
235  }
236  $this->_array[] = $bytes;
238  }
239  } while ($has_datas);
240 
241  fclose($fp);
242  }
243 
249  public function setPointer($charOffset)
250  {
251  if ($charOffset > $this->_array_size) {
252  $charOffset = $this->_array_size;
253  } elseif ($charOffset < 0) {
254  $charOffset = 0;
255  }
256  $this->_offset = $charOffset;
257  }
258 
262  public function flushContents()
263  {
264  $this->_offset = 0;
265  $this->_array = array();
266  $this->_array_size = 0;
267  }
268 
269  private function _reloadBuffer($fp, $len)
270  {
271  if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) {
272  $buf = array();
273  for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
274  $buf[] = self::$_byteMap[$bytes[$i]];
275  }
276 
277  return $buf;
278  }
279 
280  return false;
281  }
282 
283  private static function _initializeMaps()
284  {
285  if (!isset(self::$_charMap)) {
286  self::$_charMap = array();
287  for ($byte = 0; $byte < 256; ++$byte) {
288  self::$_charMap[$byte] = chr($byte);
289  }
290  self::$_byteMap = array_flip(self::$_charMap);
291  }
292  }
293 }