diff options
author | Yuchen Pei <hi@ypei.me> | 2021-10-15 09:52:00 +1100 |
---|---|---|
committer | Yuchen Pei <hi@ypei.me> | 2021-10-15 09:52:00 +1100 |
commit | 71b0e901f5fb1cfcd162d8acc23120d3f77a3152 (patch) | |
tree | 323c00faef1edc7dea2e88ff581cc2258b2b6432 /External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php | |
parent | 72cce24864b064b5762f4fe97fdf40d8d2ad4b51 (diff) | |
parent | 07f5140771388c9e0c8a99b0dd2e5d950bdb173b (diff) |
Merge branch 'development' into h-node
Diffstat (limited to 'External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php')
-rwxr-xr-x | External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php b/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php new file mode 100755 index 0000000..9612365 --- /dev/null +++ b/External/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php @@ -0,0 +1,319 @@ +<?php + +/* + * This file is part of SwiftMailer. + * (c) 2004-2009 Chris Corbyn + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +//@require 'Swift/CharacterStream.php'; +//@require 'Swift/OutputByteStream.php'; + + +/** + * A CharacterStream implementation which stores characters in an internal array. + * @package Swift + * @subpackage CharacterStream + * @author Chris Corbyn + */ +class Swift_CharacterStream_ArrayCharacterStream + implements Swift_CharacterStream +{ + + /** A map of byte values and their respective characters */ + private static $_charMap; + + /** A map of characters and their derivative byte values */ + private static $_byteMap; + + /** The char reader (lazy-loaded) for the current charset */ + private $_charReader; + + /** A factory for creatiing CharacterReader instances */ + private $_charReaderFactory; + + /** The character set this stream is using */ + private $_charset; + + /** Array of characters */ + private $_array = array(); + + /** Size of the array of character */ + private $_array_size = array(); + + /** The current character offset in the stream */ + private $_offset = 0; + + /** + * Create a new CharacterStream with the given $chars, if set. + * @param Swift_CharacterReaderFactory $factory for loading validators + * @param string $charset used in the stream + */ + public function __construct(Swift_CharacterReaderFactory $factory, + $charset) + { + self::_initializeMaps(); + $this->setCharacterReaderFactory($factory); + $this->setCharacterSet($charset); + } + + /** + * Set the character set used in this CharacterStream. + * @param string $charset + */ + public function setCharacterSet($charset) + { + $this->_charset = $charset; + $this->_charReader = null; + } + + /** + * Set the CharacterReaderFactory for multi charset support. + * @param Swift_CharacterReaderFactory $factory + */ + public function setCharacterReaderFactory( + Swift_CharacterReaderFactory $factory) + { + $this->_charReaderFactory = $factory; + } + + /** + * Overwrite this character stream using the byte sequence in the byte stream. + * @param Swift_OutputByteStream $os output stream to read from + */ + public function importByteStream(Swift_OutputByteStream $os) + { + if (!isset($this->_charReader)) + { + $this->_charReader = $this->_charReaderFactory + ->getReaderFor($this->_charset); + } + + $startLength = $this->_charReader->getInitialByteSize(); + while (false !== $bytes = $os->read($startLength)) + { + $c = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $c[] = self::$_byteMap[$bytes[$i]]; + } + $size = count($c); + $need = $this->_charReader + ->validateByteSequence($c, $size); + if ($need > 0 && + false !== $bytes = $os->read($need)) + { + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $c[] = self::$_byteMap[$bytes[$i]]; + } + } + $this->_array[] = $c; + ++$this->_array_size; + } + } + + /** + * Import a string a bytes into this CharacterStream, overwriting any existing + * data in the stream. + * @param string $string + */ + public function importString($string) + { + $this->flushContents(); + $this->write($string); + } + + /** + * Read $length characters from the stream and move the internal pointer + * $length further into the stream. + * @param int $length + * @return string + */ + public function read($length) + { + if ($this->_offset == $this->_array_size) + { + return false; + } + + // Don't use array slice + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) + { + if (!isset($this->_array[$i])) + { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += $i - $this->_offset; // Limit function calls + $chars = false; + foreach ($arrays as $array) + { + $chars .= implode('', array_map('chr', $array)); + } + return $chars; + } + + /** + * Read $length characters from the stream and return a 1-dimensional array + * containing there octet values. + * @param int $length + * @return int[] + */ + public function readBytes($length) + { + if ($this->_offset == $this->_array_size) + { + return false; + } + $arrays = array(); + $end = $length + $this->_offset; + for ($i = $this->_offset; $i < $end; ++$i) + { + if (!isset($this->_array[$i])) + { + break; + } + $arrays[] = $this->_array[$i]; + } + $this->_offset += ($i - $this->_offset); // Limit function calls + return call_user_func_array('array_merge', $arrays); + } + + /** + * Write $chars to the end of the stream. + * @param string $chars + */ + public function write($chars) + { + if (!isset($this->_charReader)) + { + $this->_charReader = $this->_charReaderFactory->getReaderFor( + $this->_charset); + } + + $startLength = $this->_charReader->getInitialByteSize(); + + $fp = fopen('php://memory', 'w+b'); + fwrite($fp, $chars); + unset($chars); + fseek($fp, 0, SEEK_SET); + + $buffer = array(0); + $buf_pos = 1; + $buf_len = 1; + $has_datas = true; + do + { + $bytes = array(); + // Buffer Filing + if ($buf_len - $buf_pos < $startLength) + { + $buf = array_splice($buffer, $buf_pos); + $new = $this->_reloadBuffer($fp, 100); + if ($new) + { + $buffer = array_merge($buf, $new); + $buf_len = count($buffer); + $buf_pos = 0; + } + else + { + $has_datas = false; + } + } + if ($buf_len - $buf_pos > 0) + { + $size = 0; + for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) + { + ++$size; + $bytes[] = $buffer[$buf_pos++]; + } + $need = $this->_charReader->validateByteSequence( + $bytes, $size); + if ($need > 0) + { + if ($buf_len - $buf_pos < $need) + { + $new = $this->_reloadBuffer($fp, $need); + + if ($new) + { + $buffer = array_merge($buffer, $new); + $buf_len = count($buffer); + } + } + for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) + { + $bytes[] = $buffer[$buf_pos++]; + } + } + $this->_array[] = $bytes; + ++$this->_array_size; + } + } + while ($has_datas); + + fclose($fp); + } + + /** + * Move the internal pointer to $charOffset in the stream. + * @param int $charOffset + */ + public function setPointer($charOffset) + { + if ($charOffset > $this->_array_size) + { + $charOffset = $this->_array_size; + } + elseif ($charOffset < 0) + { + $charOffset = 0; + } + $this->_offset = $charOffset; + } + + /** + * Empty the stream and reset the internal pointer. + */ + public function flushContents() + { + $this->_offset = 0; + $this->_array = array(); + $this->_array_size = 0; + } + + private function _reloadBuffer($fp, $len) + { + if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) + { + $buf = array(); + for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) + { + $buf[] = self::$_byteMap[$bytes[$i]]; + } + return $buf; + } + return false; + } + + private static function _initializeMaps() + { + if (!isset(self::$_charMap)) + { + self::$_charMap = array(); + for ($byte = 0; $byte < 256; ++$byte) + { + self::$_charMap[$byte] = chr($byte); + } + self::$_byteMap = array_flip(self::$_charMap); + } + } +} |