PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/ArrayCharacterStream.php

https://gitlab.com/techniconline/kmc
PHP | 294 lines | 184 code | 32 blank | 78 comment | 32 complexity | f7142d72dbd49ebf94ac91beb004d29a MD5 | raw file
  1. <?php
  2. /*
  3. * This file is part of SwiftMailer.
  4. * (c) 2004-2009 Chris Corbyn
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * A CharacterStream implementation which stores characters in an internal array.
  11. *
  12. * @author Chris Corbyn
  13. */
  14. class Swift_CharacterStream_ArrayCharacterStream implements Swift_CharacterStream
  15. {
  16. /** A map of byte values and their respective characters */
  17. private static $_charMap;
  18. /** A map of characters and their derivative byte values */
  19. private static $_byteMap;
  20. /** The char reader (lazy-loaded) for the current charset */
  21. private $_charReader;
  22. /** A factory for creating CharacterReader instances */
  23. private $_charReaderFactory;
  24. /** The character set this stream is using */
  25. private $_charset;
  26. /** Array of characters */
  27. private $_array = array();
  28. /** Size of the array of character */
  29. private $_array_size = array();
  30. /** The current character offset in the stream */
  31. private $_offset = 0;
  32. /**
  33. * Create a new CharacterStream with the given $chars, if set.
  34. *
  35. * @param Swift_CharacterReaderFactory $factory for loading validators
  36. * @param string $charset used in the stream
  37. */
  38. public function __construct(Swift_CharacterReaderFactory $factory, $charset)
  39. {
  40. self::_initializeMaps();
  41. $this->setCharacterReaderFactory($factory);
  42. $this->setCharacterSet($charset);
  43. }
  44. /**
  45. * Set the character set used in this CharacterStream.
  46. *
  47. * @param string $charset
  48. */
  49. public function setCharacterSet($charset)
  50. {
  51. $this->_charset = $charset;
  52. $this->_charReader = null;
  53. }
  54. /**
  55. * Set the CharacterReaderFactory for multi charset support.
  56. *
  57. * @param Swift_CharacterReaderFactory $factory
  58. */
  59. public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
  60. {
  61. $this->_charReaderFactory = $factory;
  62. }
  63. /**
  64. * Overwrite this character stream using the byte sequence in the byte stream.
  65. *
  66. * @param Swift_OutputByteStream $os output stream to read from
  67. */
  68. public function importByteStream(Swift_OutputByteStream $os)
  69. {
  70. if (!isset($this->_charReader)) {
  71. $this->_charReader = $this->_charReaderFactory
  72. ->getReaderFor($this->_charset);
  73. }
  74. $startLength = $this->_charReader->getInitialByteSize();
  75. while (false !== $bytes = $os->read($startLength)) {
  76. $c = array();
  77. for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
  78. $c[] = self::$_byteMap[$bytes[$i]];
  79. }
  80. $size = count($c);
  81. $need = $this->_charReader
  82. ->validateByteSequence($c, $size);
  83. if ($need > 0 &&
  84. false !== $bytes = $os->read($need)
  85. ) {
  86. for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
  87. $c[] = self::$_byteMap[$bytes[$i]];
  88. }
  89. }
  90. $this->_array[] = $c;
  91. ++$this->_array_size;
  92. }
  93. }
  94. /**
  95. * Import a string a bytes into this CharacterStream, overwriting any existing
  96. * data in the stream.
  97. *
  98. * @param string $string
  99. */
  100. public function importString($string)
  101. {
  102. $this->flushContents();
  103. $this->write($string);
  104. }
  105. /**
  106. * Read $length characters from the stream and move the internal pointer
  107. * $length further into the stream.
  108. *
  109. * @param int $length
  110. *
  111. * @return string
  112. */
  113. public function read($length)
  114. {
  115. if ($this->_offset == $this->_array_size) {
  116. return false;
  117. }
  118. // Don't use array slice
  119. $arrays = array();
  120. $end = $length + $this->_offset;
  121. for ($i = $this->_offset; $i < $end; ++$i) {
  122. if (!isset($this->_array[$i])) {
  123. break;
  124. }
  125. $arrays[] = $this->_array[$i];
  126. }
  127. $this->_offset += $i - $this->_offset; // Limit function calls
  128. $chars = false;
  129. foreach ($arrays as $array) {
  130. $chars .= implode('', array_map('chr', $array));
  131. }
  132. return $chars;
  133. }
  134. /**
  135. * Read $length characters from the stream and return a 1-dimensional array
  136. * containing there octet values.
  137. *
  138. * @param int $length
  139. *
  140. * @return integer[]
  141. */
  142. public function readBytes($length)
  143. {
  144. if ($this->_offset == $this->_array_size) {
  145. return false;
  146. }
  147. $arrays = array();
  148. $end = $length + $this->_offset;
  149. for ($i = $this->_offset; $i < $end; ++$i) {
  150. if (!isset($this->_array[$i])) {
  151. break;
  152. }
  153. $arrays[] = $this->_array[$i];
  154. }
  155. $this->_offset += ($i - $this->_offset); // Limit function calls
  156. return call_user_func_array('array_merge', $arrays);
  157. }
  158. /**
  159. * Write $chars to the end of the stream.
  160. *
  161. * @param string $chars
  162. */
  163. public function write($chars)
  164. {
  165. if (!isset($this->_charReader)) {
  166. $this->_charReader = $this->_charReaderFactory->getReaderFor(
  167. $this->_charset);
  168. }
  169. $startLength = $this->_charReader->getInitialByteSize();
  170. $fp = fopen('php://memory', 'w+b');
  171. fwrite($fp, $chars);
  172. unset($chars);
  173. fseek($fp, 0, SEEK_SET);
  174. $buffer = array(0);
  175. $buf_pos = 1;
  176. $buf_len = 1;
  177. $has_datas = true;
  178. do {
  179. $bytes = array();
  180. // Buffer Filing
  181. if ($buf_len - $buf_pos < $startLength) {
  182. $buf = array_splice($buffer, $buf_pos);
  183. $new = $this->_reloadBuffer($fp, 100);
  184. if ($new) {
  185. $buffer = array_merge($buf, $new);
  186. $buf_len = count($buffer);
  187. $buf_pos = 0;
  188. } else {
  189. $has_datas = false;
  190. }
  191. }
  192. if ($buf_len - $buf_pos > 0) {
  193. $size = 0;
  194. for ($i = 0; $i < $startLength && isset($buffer[$buf_pos]); ++$i) {
  195. ++$size;
  196. $bytes[] = $buffer[$buf_pos++];
  197. }
  198. $need = $this->_charReader->validateByteSequence(
  199. $bytes, $size);
  200. if ($need > 0) {
  201. if ($buf_len - $buf_pos < $need) {
  202. $new = $this->_reloadBuffer($fp, $need);
  203. if ($new) {
  204. $buffer = array_merge($buffer, $new);
  205. $buf_len = count($buffer);
  206. }
  207. }
  208. for ($i = 0; $i < $need && isset($buffer[$buf_pos]); ++$i) {
  209. $bytes[] = $buffer[$buf_pos++];
  210. }
  211. }
  212. $this->_array[] = $bytes;
  213. ++$this->_array_size;
  214. }
  215. } while ($has_datas);
  216. fclose($fp);
  217. }
  218. /**
  219. * Move the internal pointer to $charOffset in the stream.
  220. *
  221. * @param int $charOffset
  222. */
  223. public function setPointer($charOffset)
  224. {
  225. if ($charOffset > $this->_array_size) {
  226. $charOffset = $this->_array_size;
  227. } elseif ($charOffset < 0) {
  228. $charOffset = 0;
  229. }
  230. $this->_offset = $charOffset;
  231. }
  232. /**
  233. * Empty the stream and reset the internal pointer.
  234. */
  235. public function flushContents()
  236. {
  237. $this->_offset = 0;
  238. $this->_array = array();
  239. $this->_array_size = 0;
  240. }
  241. private function _reloadBuffer($fp, $len)
  242. {
  243. if (!feof($fp) && ($bytes = fread($fp, $len)) !== false) {
  244. $buf = array();
  245. for ($i = 0, $len = strlen($bytes); $i < $len; ++$i) {
  246. $buf[] = self::$_byteMap[$bytes[$i]];
  247. }
  248. return $buf;
  249. }
  250. return false;
  251. }
  252. private static function _initializeMaps()
  253. {
  254. if (!isset(self::$_charMap)) {
  255. self::$_charMap = array();
  256. for ($byte = 0; $byte < 256; ++$byte) {
  257. self::$_charMap[$byte] = chr($byte);
  258. }
  259. self::$_byteMap = array_flip(self::$_charMap);
  260. }
  261. }
  262. }