TYPO3 API  SVNRelease
NgCharacterStream.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  CharacterStream implementation using an array in Swift Mailer.
00005 
00006  This program is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  This program is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019  */
00020 
00021 //@require 'Swift/CharacterStream.php';
00022 //@require 'Swift/OutputByteStream.php';
00023 
00024 
00025 /**
00026  * A CharacterStream implementation which stores characters in an internal array.
00027  * @package Swift
00028  * @subpackage CharacterStream
00029  * @author Xavier De Cock <xdecock@gmail.com>
00030  */
00031 
00032 Class Swift_CharacterStream_NgCharacterStream
00033   implements Swift_CharacterStream
00034 {
00035 
00036   /**
00037    * The char reader (lazy-loaded) for the current charset.
00038    * @var Swift_CharacterReader
00039    * @access private
00040    */
00041   private $_charReader;
00042 
00043   /**
00044    * A factory for creatiing CharacterReader instances.
00045    * @var Swift_CharacterReaderFactory
00046    * @access private
00047    */
00048   private $_charReaderFactory;
00049 
00050   /**
00051    * The character set this stream is using.
00052    * @var string
00053    * @access private
00054    */
00055   private $_charset;
00056 
00057   /**
00058    * The datas stored as is
00059    *
00060    * @var string
00061    */
00062   private $_datas = "";
00063 
00064   /**
00065    * Number of bytes in the stream
00066    *
00067    * @var int
00068    */
00069   private $_datasSize = 0;
00070 
00071   /**
00072    * Map
00073    *
00074    * @var mixed
00075    */
00076   private $_map;
00077 
00078   /**
00079    * Map Type
00080    *
00081    * @var int
00082    */
00083   private $_mapType = 0;
00084 
00085   /**
00086    * Number of characters in the stream
00087    *
00088    * @var int
00089    */
00090   private $_charCount = 0;
00091 
00092   /**
00093    * Position in the stream
00094    *
00095    * @var unknown_type
00096    */
00097   private $_currentPos = 0;
00098 
00099   /**
00100    * The constructor
00101    *
00102    * @param Swift_CharacterReaderFactory $factory
00103    * @param unknown_type $charset
00104    */
00105   public function __construct(Swift_CharacterReaderFactory $factory,
00106     $charset)
00107   {
00108     $this->setCharacterReaderFactory($factory);
00109     $this->setCharacterSet($charset);
00110   }
00111 
00112   /* -- Changing parameters of the stream -- */
00113 
00114   /**
00115    * Set the character set used in this CharacterStream.
00116    * @param string $charset
00117    */
00118   public function setCharacterSet($charset)
00119   {
00120     $this->_charset = $charset;
00121     $this->_charReader = null;
00122     $this->_mapType = 0;
00123   }
00124 
00125   /**
00126    * Set the CharacterReaderFactory for multi charset support.
00127    * @param Swift_CharacterReaderFactory $factory
00128    */
00129   public function setCharacterReaderFactory(
00130     Swift_CharacterReaderFactory $factory)
00131   {
00132     $this->_charReaderFactory = $factory;
00133   }
00134 
00135   /**
00136    * @see Swift_CharacterStream::flushContents()
00137    *
00138    */
00139   public function flushContents()
00140   {
00141     $this->_datas = null;
00142     $this->_map = null;
00143     $this->_charCount = 0;
00144     $this->_currentPos = 0;
00145     $this->_datasSize = 0;
00146   }
00147 
00148   /**
00149    * @see Swift_CharacterStream::importByteStream()
00150    *
00151    * @param Swift_OutputByteStream $os
00152    */
00153   public function importByteStream(Swift_OutputByteStream $os)
00154   {
00155     $this->flushContents();
00156     $blocks=512;
00157     $os->setReadPointer(0);
00158     while(false!==($read = $os->read($blocks)))
00159       $this->write($read);
00160   }
00161 
00162   /**
00163    * @see Swift_CharacterStream::importString()
00164    *
00165    * @param string $string
00166    */
00167   public function importString($string)
00168   {
00169     $this->flushContents();
00170     $this->write($string);
00171   }
00172 
00173   /**
00174    * @see Swift_CharacterStream::read()
00175    *
00176    * @param int $length
00177    * @return string
00178    */
00179   public function read($length)
00180   {
00181     if ($this->_currentPos>=$this->_charCount)
00182     {
00183       return false;
00184     }
00185     $ret=false;
00186     $length = ($this->_currentPos+$length > $this->_charCount)
00187       ? $this->_charCount - $this->_currentPos
00188       : $length;
00189       switch ($this->_mapType)
00190     {
00191       case Swift_CharacterReader::MAP_TYPE_FIXED_LEN:
00192         $len = $length*$this->_map;
00193         $ret = substr($this->_datas,
00194             $this->_currentPos * $this->_map,
00195             $len);
00196         $this->_currentPos += $length;
00197         break;
00198 
00199       case Swift_CharacterReader::MAP_TYPE_INVALID:
00200         $end = $this->_currentPos + $length;
00201         $end = $end > $this->_charCount
00202           ?$this->_charCount
00203           :$end;
00204         $ret = '';
00205         for (; $this->_currentPos < $length; ++$this->_currentPos)
00206         {
00207           if (isset ($this->_map[$this->_currentPos]))
00208           {
00209             $ret .= '?';
00210           }
00211           else
00212           {
00213             $ret .= $this->_datas[$this->_currentPos];
00214           }
00215         }
00216         break;
00217 
00218       case Swift_CharacterReader::MAP_TYPE_POSITIONS:
00219         $end = $this->_currentPos + $length;
00220         $end = $end > $this->_charCount
00221           ?$this->_charCount
00222           :$end;
00223         $ret = '';
00224         $start = 0;
00225         if ($this->_currentPos>0)
00226         {
00227           $start = $this->_map['p'][$this->_currentPos-1];
00228         }
00229         $to = $start;
00230         for (; $this->_currentPos < $end; ++$this->_currentPos)
00231         {
00232           if (isset($this->_map['i'][$this->_currentPos])) {
00233             $ret .= substr($this->_datas, $start, $to - $start).'?';
00234             $start = $this->_map['p'][$this->_currentPos];
00235           } else {
00236             $to = $this->_map['p'][$this->_currentPos];
00237           }
00238         }
00239         $ret .= substr($this->_datas, $start, $to - $start);
00240         break;
00241     }
00242     return $ret;
00243   }
00244 
00245   /**
00246    * @see Swift_CharacterStream::readBytes()
00247    *
00248    * @param int $length
00249    * @return int[]
00250    */
00251   public function readBytes($length)
00252   {
00253     $read=$this->read($length);
00254     if ($read!==false)
00255     {
00256       $ret = array_map('ord', str_split($read, 1));
00257       return $ret;
00258     }
00259     return false;
00260   }
00261 
00262   /**
00263    * @see Swift_CharacterStream::setPointer()
00264    *
00265    * @param int $charOffset
00266    */
00267   public function setPointer($charOffset)
00268   {
00269     if ($this->_charCount<$charOffset){
00270         $charOffset=$this->_charCount;
00271     }
00272     $this->_currentPos = $charOffset;
00273   }
00274 
00275   /**
00276    * @see Swift_CharacterStream::write()
00277    *
00278    * @param string $chars
00279    */
00280   public function write($chars)
00281   {
00282     if (!isset($this->_charReader))
00283     {
00284       $this->_charReader = $this->_charReaderFactory->getReaderFor(
00285         $this->_charset);
00286       $this->_map = array();
00287       $this->_mapType = $this->_charReader->getMapType();
00288     }
00289     $ignored='';
00290     $this->_datas .= $chars;
00291     $this->_charCount += $this->_charReader->getCharPositions(substr($this->_datas, $this->_datasSize), $this->_datasSize, $this->_map, $ignored);
00292     if ($ignored!==false) {
00293       $this->_datasSize=strlen($this->_datas)-strlen($ignored);
00294     }
00295     else
00296     {
00297       $this->_datasSize=strlen($this->_datas);
00298     }
00299   }
00300 }