PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/classes/Swift/CharacterStream/NgCharacterStream.php

http://github.com/swiftmailer/swiftmailer
PHP | 262 lines | 130 code | 26 blank | 106 comment | 15 complexity | c3c95ea0a4ea5df03844e5a415c6dacf MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
  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 Xavier De Cock <xdecock@gmail.com>
  13. */
  14. class Swift_CharacterStream_NgCharacterStream implements Swift_CharacterStream
  15. {
  16. /**
  17. * The char reader (lazy-loaded) for the current charset.
  18. *
  19. * @var Swift_CharacterReader
  20. */
  21. private $charReader;
  22. /**
  23. * A factory for creating CharacterReader instances.
  24. *
  25. * @var Swift_CharacterReaderFactory
  26. */
  27. private $charReaderFactory;
  28. /**
  29. * The character set this stream is using.
  30. *
  31. * @var string
  32. */
  33. private $charset;
  34. /**
  35. * The data's stored as-is.
  36. *
  37. * @var string
  38. */
  39. private $datas = '';
  40. /**
  41. * Number of bytes in the stream.
  42. *
  43. * @var int
  44. */
  45. private $datasSize = 0;
  46. /**
  47. * Map.
  48. *
  49. * @var mixed
  50. */
  51. private $map;
  52. /**
  53. * Map Type.
  54. *
  55. * @var int
  56. */
  57. private $mapType = 0;
  58. /**
  59. * Number of characters in the stream.
  60. *
  61. * @var int
  62. */
  63. private $charCount = 0;
  64. /**
  65. * Position in the stream.
  66. *
  67. * @var int
  68. */
  69. private $currentPos = 0;
  70. /**
  71. * Constructor.
  72. *
  73. * @param string $charset
  74. */
  75. public function __construct(Swift_CharacterReaderFactory $factory, $charset)
  76. {
  77. $this->setCharacterReaderFactory($factory);
  78. $this->setCharacterSet($charset);
  79. }
  80. /* -- Changing parameters of the stream -- */
  81. /**
  82. * Set the character set used in this CharacterStream.
  83. *
  84. * @param string $charset
  85. */
  86. public function setCharacterSet($charset)
  87. {
  88. $this->charset = $charset;
  89. $this->charReader = null;
  90. $this->mapType = 0;
  91. }
  92. /**
  93. * Set the CharacterReaderFactory for multi charset support.
  94. */
  95. public function setCharacterReaderFactory(Swift_CharacterReaderFactory $factory)
  96. {
  97. $this->charReaderFactory = $factory;
  98. }
  99. /**
  100. * @see Swift_CharacterStream::flushContents()
  101. */
  102. public function flushContents()
  103. {
  104. $this->datas = null;
  105. $this->map = null;
  106. $this->charCount = 0;
  107. $this->currentPos = 0;
  108. $this->datasSize = 0;
  109. }
  110. /**
  111. * @see Swift_CharacterStream::importByteStream()
  112. */
  113. public function importByteStream(Swift_OutputByteStream $os)
  114. {
  115. $this->flushContents();
  116. $blocks = 512;
  117. $os->setReadPointer(0);
  118. while (false !== ($read = $os->read($blocks))) {
  119. $this->write($read);
  120. }
  121. }
  122. /**
  123. * @see Swift_CharacterStream::importString()
  124. *
  125. * @param string $string
  126. */
  127. public function importString($string)
  128. {
  129. $this->flushContents();
  130. $this->write($string);
  131. }
  132. /**
  133. * @see Swift_CharacterStream::read()
  134. *
  135. * @param int $length
  136. *
  137. * @return string
  138. */
  139. public function read($length)
  140. {
  141. if ($this->currentPos >= $this->charCount) {
  142. return false;
  143. }
  144. $ret = false;
  145. $length = ($this->currentPos + $length > $this->charCount) ? $this->charCount - $this->currentPos : $length;
  146. switch ($this->mapType) {
  147. case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
  148. $len = $length * $this->map;
  149. $ret = substr($this->datas,
  150. $this->currentPos * $this->map,
  151. $len);
  152. $this->currentPos += $length;
  153. break;
  154. case Swift_CharacterReader::MAP_TYPE_INVALID:
  155. $ret = '';
  156. for (; $this->currentPos < $length; ++$this->currentPos) {
  157. if (isset($this->map[$this->currentPos])) {
  158. $ret .= '?';
  159. } else {
  160. $ret .= $this->datas[$this->currentPos];
  161. }
  162. }
  163. break;
  164. case Swift_CharacterReader::MAP_TYPE_POSITIONS:
  165. $end = $this->currentPos + $length;
  166. $end = $end > $this->charCount ? $this->charCount : $end;
  167. $ret = '';
  168. $start = 0;
  169. if ($this->currentPos > 0) {
  170. $start = $this->map['p'][$this->currentPos - 1];
  171. }
  172. $to = $start;
  173. for (; $this->currentPos < $end; ++$this->currentPos) {
  174. if (isset($this->map['i'][$this->currentPos])) {
  175. $ret .= substr($this->datas, $start, $to - $start).'?';
  176. $start = $this->map['p'][$this->currentPos];
  177. } else {
  178. $to = $this->map['p'][$this->currentPos];
  179. }
  180. }
  181. $ret .= substr($this->datas, $start, $to - $start);
  182. break;
  183. }
  184. return $ret;
  185. }
  186. /**
  187. * @see Swift_CharacterStream::readBytes()
  188. *
  189. * @param int $length
  190. *
  191. * @return int[]
  192. */
  193. public function readBytes($length)
  194. {
  195. $read = $this->read($length);
  196. if (false !== $read) {
  197. $ret = array_map('ord', str_split($read, 1));
  198. return $ret;
  199. }
  200. return false;
  201. }
  202. /**
  203. * @see Swift_CharacterStream::setPointer()
  204. *
  205. * @param int $charOffset
  206. */
  207. public function setPointer($charOffset)
  208. {
  209. if ($this->charCount < $charOffset) {
  210. $charOffset = $this->charCount;
  211. }
  212. $this->currentPos = $charOffset;
  213. }
  214. /**
  215. * @see Swift_CharacterStream::write()
  216. *
  217. * @param string $chars
  218. */
  219. public function write($chars)
  220. {
  221. if (!isset($this->charReader)) {
  222. $this->charReader = $this->charReaderFactory->getReaderFor(
  223. $this->charset);
  224. $this->map = [];
  225. $this->mapType = $this->charReader->getMapType();
  226. }
  227. $ignored = '';
  228. $this->datas .= $chars;
  229. $this->charCount += $this->charReader->getCharPositions(substr($this->datas, $this->datasSize), $this->datasSize, $this->map, $ignored);
  230. if (false !== $ignored) {
  231. $this->datasSize = strlen($this->datas) - strlen($ignored);
  232. } else {
  233. $this->datasSize = strlen($this->datas);
  234. }
  235. }
  236. }