Seditio Source
Root |
./othercms/elxis_5.3_atlas_rev2452/includes/libraries/swift/classes/Swift/CharacterStream/ArrayCharacterStream.php
<?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.
 */

/**
 * A CharacterStream implementation which stores characters in an internal array.
 *
 * @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 creating 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);
        }
    }
}