text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Table.php 23953 2011-05-03 05:47:39Z ralph $
 */

/**
 * Zend_Text_Table enables developers to create tables out of characters
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table
{
    /**
     * Auto seperator settings
     */
    const AUTO_SEPARATE_NONE   = 0x0;
    const AUTO_SEPARATE_HEADER = 0x1;
    const AUTO_SEPARATE_FOOTER = 0x2;
    const AUTO_SEPARATE_ALL    = 0x4;

    /**
     * Decorator used for the table borders
     *
     * @var Zend_Text_Table_Decorator_Interface
     */
    protected $_decorator = null;

    /**
     * List of all column widths
     *
     * @var array
     */
    protected $_columnWidths = null;

    /**
     * Rows of the table
     *
     * @var array
     */
    protected $_rows = array();

    /**
     * Auto separation mode
     *
     * @var integer
     */
    protected $_autoSeparate = self::AUTO_SEPARATE_ALL;

    /**
     * Padding for columns
     *
     * @var integer
     */
    protected $_padding = 0;

    /**
     * Default column aligns for rows created by appendRow(array $data)
     *
     * @var array
     */
    protected $_defaultColumnAligns = array();

    /**
     * Plugin loader for decorators
     *
     * @var string
     */
    protected $_pluginLoader = null;

    /**
     * Charset which is used for input by default
     *
     * @var string
     */
    protected static $_inputCharset = 'utf-8';

    /**
     * Charset which is used internally
     *
     * @var string
     */
    protected static $_outputCharset = 'utf-8';

    /**
     * Option keys to skip when calling setOptions()
     *
     * @var array
     */
    protected $_skipOptions = array(
        'options',
        'config',
        'defaultColumnAlign',
    );

    /**
     * Create a basic table object
     *
     * @param  array             $columnsWidths List of all column widths
     * @param  Zend_Config|array $options       Configuration options
     * @throws Zend_Text_Table_Exception When no columns widths were set
     */
    public function __construct($options = null)
    {
        // Set options
        if (is_array($options)) {
            $this->setOptions($options);
        } else if ($options instanceof Zend_Config) {
            $this->setConfig($options);
        }

        // Check if column widths were set
        // @todo When column widths were not set, assume auto-sizing
        if ($this->_columnWidths === null) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('You must define the column widths');
        }

        // If no decorator was given, use default unicode decorator
        if ($this->_decorator === null) {
            if (self::getOutputCharset() === 'utf-8') {
                $this->setDecorator('unicode');
            } else {
                $this->setDecorator('ascii');
            }
        }
    }

    /**
     * Set options from array
     *
     * @param  array $options Configuration for Zend_Text_Table
     * @return Zend_Text_Table
     */
    public function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            if (in_array(strtolower($key), $this->_skipOptions)) {
                continue;
            }

            $method = 'set' . ucfirst($key);
            if (method_exists($this, $method)) {
                $this->$method($value);
            }
        }

        return $this;
    }

    /**
     * Set options from config object
     *
     * @param  Zend_Config $config Configuration for Zend_Text_Table
     * @return Zend_Text_Table
     */
    public function setConfig(Zend_Config $config)
    {
        return $this->setOptions($config->toArray());
    }

    /**
     * Set column widths
     *
     * @param  array $columnWidths Widths of all columns
     * @throws Zend_Text_Table_Exception When no columns were supplied
     * @throws Zend_Text_Table_Exception When a column has an invalid width
     * @return Zend_Text_Table
     */
    public function setColumnWidths(array $columnWidths)
    {
        if (count($columnWidths) === 0) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('You must supply at least one column');
        }

        foreach ($columnWidths as $columnNum => $columnWidth) {
            if (is_int($columnWidth) === false or $columnWidth < 1) {
                require_once 'Zend/Text/Table/Exception.php';
                throw new Zend_Text_Table_Exception('Column ' . $columnNum . ' has an invalid'
                                                    . ' column width');
            }
        }

        $this->_columnWidths = $columnWidths;

        return $this;
    }

    /**
     * Set auto separation mode
     *
     * @param  integer $autoSeparate Auto separation mode
     * @return Zend_Text_Table
     */
    public function setAutoSeparate($autoSeparate)
    {
        $this->_autoSeparate = (int) $autoSeparate;
        return $this;
    }

    /**
     * Set decorator
     *
     * @param  Zend_Text_Table_Decorator_Interface|string $decorator Decorator to use
     * @return Zend_Text_Table
     */
    public function setDecorator($decorator)
    {
        if ($decorator instanceof Zend_Text_Table_Decorator_Interface) {
            $this->_decorator = $decorator;
        } else {
            $classname        = $this->getPluginLoader()->load($decorator);
            $this->_decorator = new $classname;
        }

        return $this;
    }

    /**
     * Set the column padding
     *
     * @param  integer $padding The padding for the columns
     * @return Zend_Text_Table
     */
    public function setPadding($padding)
    {
        $this->_padding = max(0, (int) $padding);
        return $this;
    }

    /**
     * Get the plugin loader for decorators
     *
     * @return Zend_Loader_PluginLoader
     */
    public function getPluginLoader()
    {
        if ($this->_pluginLoader === null) {
            $prefix     = 'Zend_Text_Table_Decorator_';
            $pathPrefix = 'Zend/Text/Table/Decorator/';

            require_once 'Zend/Loader/PluginLoader.php';
            $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix));
        }

        return $this->_pluginLoader;
    }

    /**
     * Set default column align for rows created by appendRow(array $data)
     *
     * @param  integer $columnNum
     * @param  string  $align
     * @return Zend_Text_Table
     */
    public function setDefaultColumnAlign($columnNum, $align)
    {
        $this->_defaultColumnAligns[$columnNum] = $align;

        return $this;
    }

    /**
     * Set the input charset for column contents
     *
     * @param string $charset
     */
    public static function setInputCharset($charset)
    {
        self::$_inputCharset = strtolower($charset);
    }

    /**
     * Get the input charset for column contents
     *
     * @param string $charset
     */
    public static function getInputCharset()
    {
        return self::$_inputCharset;
    }

    /**
     * Set the output charset for column contents
     *
     * @param string $charset
     */
    public static function setOutputCharset($charset)
    {
        self::$_outputCharset = strtolower($charset);
    }

    /**
     * Get the output charset for column contents
     *
     * @param string $charset
     */
    public static function getOutputCharset()
    {
        return self::$_outputCharset;
    }

    /**
     * Append a row to the table
     *
     * @param  array|Zend_Text_Table_Row $row The row to append to the table
     * @throws Zend_Text_Table_Exception When $row is neither an array nor Zend_Zext_Table_Row
     * @throws Zend_Text_Table_Exception When a row contains too many columns
     * @return Zend_Text_Table
     */
    public function appendRow($row)
    {
        if (!is_array($row) && !($row instanceof Zend_Text_Table_Row)) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('$row must be an array or instance of Zend_Text_Table_Row');
        }

        if (is_array($row)) {
            if (count($row) > count($this->_columnWidths)) {
                require_once 'Zend/Text/Table/Exception.php';
                throw new Zend_Text_Table_Exception('Row contains too many columns');
            }

            require_once 'Zend/Text/Table/Row.php';
            require_once 'Zend/Text/Table/Column.php';

            $data   = $row;
            $row    = new Zend_Text_Table_Row();
            $colNum = 0;
            foreach ($data as $columnData) {
                if (isset($this->_defaultColumnAligns[$colNum])) {
                    $align = $this->_defaultColumnAligns[$colNum];
                } else {
                    $align = null;
                }

                $row->appendColumn(new Zend_Text_Table_Column($columnData, $align));
                $colNum++;
            }
        }

        $this->_rows[] = $row;

        return $this;
    }

    /**
     * Render the table
     *
     * @throws Zend_Text_Table_Exception When no rows were added to the table
     * @return string
     */
    public function render()
    {
        // There should be at least one row
        if (count($this->_rows) === 0) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('No rows were added to the table yet');
        }

        // Initiate the result variable
        $result = '';

        // Count total columns
        $totalNumColumns = count($this->_columnWidths);

        // Now render all rows, starting from the first one
        $numRows = count($this->_rows);
        foreach ($this->_rows as $rowNum => $row) {
            // Get all column widths
            if (isset($columnWidths) === true) {
                $lastColumnWidths = $columnWidths;
            }

            $renderedRow  = $row->render($this->_columnWidths, $this->_decorator, $this->_padding);
            $columnWidths = $row->getColumnWidths();
            $numColumns   = count($columnWidths);

            // Check what we have to draw
            if ($rowNum === 0) {
                // If this is the first row, draw the table top
                $result .= $this->_decorator->getTopLeft();

                foreach ($columnWidths as $columnNum => $columnWidth) {
                    $result .= str_repeat($this->_decorator->getHorizontal(),
                                          $columnWidth);

                    if (($columnNum + 1) === $numColumns) {
                        $result .= $this->_decorator->getTopRight();
                    } else {
                        $result .= $this->_decorator->getHorizontalDown();
                    }
                }

                $result .= "\n";
            } else {
                // Else check if we have to draw the row separator
                if ($this->_autoSeparate & self::AUTO_SEPARATE_ALL) {
                    $drawSeparator = true;
                } else if ($rowNum === 1 && $this->_autoSeparate & self::AUTO_SEPARATE_HEADER) {
                    $drawSeparator = true;
                } else if ($rowNum === ($numRows - 1) && $this->_autoSeparate & self::AUTO_SEPARATE_FOOTER) {
                    $drawSeparator = true;
                } else {
                    $drawSeparator = false;
                }

                if ($drawSeparator) {
                    $result .= $this->_decorator->getVerticalRight();

                    $currentUpperColumn = 0;
                    $currentLowerColumn = 0;
                    $currentUpperWidth  = 0;
                    $currentLowerWidth  = 0;

                    // Loop through all column widths
                    foreach ($this->_columnWidths as $columnNum => $columnWidth) {
                        // Add the horizontal line
                        $result .= str_repeat($this->_decorator->getHorizontal(),
                                              $columnWidth);

                        // If this is the last line, break out
                        if (($columnNum + 1) === $totalNumColumns) {
                            break;
                        }

                        // Else check, which connector style has to be used
                        $connector          = 0x0;
                        $currentUpperWidth += $columnWidth;
                        $currentLowerWidth += $columnWidth;

                        if ($lastColumnWidths[$currentUpperColumn] === $currentUpperWidth) {
                            $connector          |= 0x1;
                            $currentUpperColumn += 1;
                            $currentUpperWidth   = 0;
                        } else {
                            $currentUpperWidth += 1;
                        }

                        if ($columnWidths[$currentLowerColumn] === $currentLowerWidth) {
                            $connector          |= 0x2;
                            $currentLowerColumn += 1;
                            $currentLowerWidth   = 0;
                        } else {
                            $currentLowerWidth += 1;
                        }

                        switch ($connector) {
                            case 0x0:
                                $result .= $this->_decorator->getHorizontal();
                                break;

                            case 0x1:
                                $result .= $this->_decorator->getHorizontalUp();
                                break;

                            case 0x2:
                                $result .= $this->_decorator->getHorizontalDown();
                                break;

                            case 0x3:
                                $result .= $this->_decorator->getCross();
                                break;

                            default:
                                // This can never happen, but the CS tells I have to have it ...
                                break;
                        }
                    }

                    $result .= $this->_decorator->getVerticalLeft() . "\n";
                }
            }

            // Add the rendered row to the result
            $result .= $renderedRow;

            // If this is the last row, draw the table bottom
            if (($rowNum + 1) === $numRows) {
                $result .= $this->_decorator->getBottomLeft();

                foreach ($columnWidths as $columnNum => $columnWidth) {
                    $result .= str_repeat($this->_decorator->getHorizontal(),
                                          $columnWidth);

                    if (($columnNum + 1) === $numColumns) {
                        $result .= $this->_decorator->getBottomRight();
                    } else {
                        $result .= $this->_decorator->getHorizontalUp();
                    }
                }

                $result .= "\n";
            }
        }

        return $result;
    }

    /**
     * Magic method which returns the rendered table
     *
     * @return string
     */
    public function __toString()
    {
        try {
            return $this->render();
        } catch (Exception $e) {
            trigger_error($e->getMessage(), E_USER_ERROR);
        }

    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Figlet
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Text_Exception
 */
require_once 'Zend/Text/Exception.php';

/**
 * Exception class for Zend_Figlet
 *
 * @category  Zend
 * @package   Zend_Text_Figlet
 * @uses      Zend_Text_Exception
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Figlet_Exception extends Zend_Text_Exception
{
}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
flf2a$ 7 6 10 51 22 0 7987
Author : Wil Sinclair
Date   : 2008/6/26 20:34:25
Version: 1.0

-------------------------------------------------------------------------------

 Zend Framework

 LICENSE

 This source file is subject to the new BSD license that is bundled
 with this package in the file LICENSE.txt.
 It is also available through the world-wide-web at this URL:
 http://framework.zend.com/license/new-bsd
 If you did not receive a copy of the license and are unable to
 obtain it through the world-wide-web, please send an email
 to license@zend.com so we can send you a copy immediately.

 Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)

-------------------------------------------------------------------------------

$ #
$ #
$ #
$ #
$ #
$ #
$ ##
   __   #
  /  \\ #
  |  || #
  |$ || #
   \//  #
   []|  #
        ##
   __  __ #
  / /// //#
 /_///_// #
 `-` `-`  #
          #
          #
          ##
##
 #
 #
 #
 #
 #
 ##
    _     #
   | ||_  #
  / ___// #
  \___ \\ #
  /  $ // #
 /_   //  #
 `-|_||   ##
%#
 #
 #
 #
 #
 #
 ##
&#
 #
 #
 #
 #
 #
 ##
'#
 #
 #
 #
 #
 #
 ##
(#
 #
 #
 #
 #
 #
 ##
)#
 #
 #
 #
 #
 #
 ##
*#
 #
 #
 #
 #
 #
 ##
          #
    _     #
  _| ||   #
 |_ $ _|| #
 `-|_|-`  #
    -     #
          ##
,#
 #
 #
 #
 #
 #
 ##
          #
          #
 ,------,,#
'======'' #
          #
          #
          ##
.#
 #
 #
 #
 #
 #
 ##
/#
 #
 #
 #
 #
 #
 ##
   ___    #
  / _ \\  #
 | |$| || #
 | |_| || #
  \___//  #
  `---`   #
          ##
   __     #
  /  ||   #
   | ||   #
  _| ||_  #
 |__$__|| #
 `-----`  #
          ##
 _____    #
 \___ \\  #
 / ___//  #
 | $  \\  #
 |_____\\ #
 `------` #
          ##
  _____   #
 |___  \\ #
  __$\ // #
  __$/ \\ #
 |_____// #
 `-----`  #
          ##
    __    #
   /  ||  #
  / /|||_ #
 /__ $ _||#
    |_||  #
    `-`   #
          ##
   _____  #
  / ___// #
 /___ \\  #
  / $ //  #
 /___//   #
`----`    #
          ##
    __   #
   / //  #
  / //   #
 / __ \\ #
 \____// #
  `---`  #
         ##
  ______  #
 |___  // #
    / //  #
   | ||   #
   |_||   #
   `-`    #
          ##
  ____   #
 /    \\ #
 \ -- // #
 / -- \\ #
 \____// #
 `----`  #
         ##
  ____    #
 / __ \\  #
 \__   || #
    / //  #
   /_//   #
   `-`    #
          ##
       #
       #
   []| #
       #
   []| #
       #
       ##
       #
   _   #
  [_]| #
   _   #
  | ]] #
  |//  #
  '    ##
<#
 #
 #
 #
 #
 #
 ##
          #
  ______  #
 /_____// #
 /_____// #
 `-----`  #
          #
          ##
>#
 #
 #
 #
 #
 #
 ##
?#
 #
 #
 #
 #
 #
 ##
@#
 #
 #
 #
 #
 #
 ##
   ___    #
  / _ \\  #
 / //\ \\ #
|  ___  ||#
|_||  |_||#
`-`   `-` #
          ##
 ______   #
|      \\ #
|  --$  // #
|  --  \\ #
|______// #
`------`  #
          ##
  _____   #
 / ____|| #
/ //---`' #
\ \\___   #
 \_____|| #
  `----`  #
          ##
 _____    #
|  __ \\  #
| |$ \ || #
| |__/ || #
|_____//  #
 -----`   #
          ##
  _____   #
 |  ___|| #
 | ||__   #
 | ||__   #
 |_____|| #
 `-----`  #
          ##
  ______  #
 /_____// #
 `____ `  #
 /___//   #
 `__ `    #
 /_//     #
 `-`      ##
  _____   #
 /  ___|| #
| //$__   #
| \\_\ || #
 \____//  #
  `---`   #
          ##
 __   _   #
| || | || #
| '--' || #
| .--. || #
|_|| |_|| #
`-`  `-`  #
          ##
  ______  #
 /_   _// #
  -| ||-  #
  _| ||_  #
 /_____// #
 `-----`  #
          ##
  ______  #
 /_   _// #
   | ||   #
  _| ||   #
 /__//    #
 `--`     #
          ##
  _  __  #
 | |/ // #
 | ' //  #
 | . \\  #
 |_|\_\\ #
 `-` --` #
         ##
  __     #
 | ||    #
 | ||    #
 | ||__  #
 |____// #
 `----`  #
         ##
 _    _   #
| \  / || #
|  \/  || #
| .  . || #
|_|\/|_|| #
`-`  `-`  #
          ##
  _  _   #
 | \| || #
 |  ' || #
 | .  || #
 |_|\_|| #
 `-` -`  #
         ##
   ___    #
  / _ \\  #
 | /$\ || #
 | \_/ || #
  \___//  #
  `---`   #
          ##
  ____    #
 |  _ \\  #
 | |_| || #
 | .__//  #
 |_|--`   #
 `-`      #
          ##
  ___    #
 / _ \\  #
| /$\ || #
| \_/ || #
 \___ \\ #
 `---`   #
         ##
  ____    #
 |  _ \\  #
 | |_| || #
 | .  //  #
 |_|\_\\  #
 `-` --`  #
          ##
   _____  #
  / ___// #
  \___ \\ #
  /  $ // #
 /____//  #
`-----`   #
          ##
  ______  #
 /_   _// #
 `-| |,-  #
   | ||   #
   |_||   #
   `-`'   #
          ##
 _    _   #
| || | || #
| || | || #
| \\_/ || #
 \____//  #
  `---`   #
          ##
__    __  #
\ \\ / // #
 \ \/ //  #
  \  //   #
   \//    #
    `     #
          ##
 _    _   #
| |  | || #
| |/\| || #
|  /\  || #
|_// \_|| #
`-`   `-` #
          ##
 __   __  #
 \ \\/ // #
  \ $ //  #
  / . \\  #
 /_//\_\\ #
 `-`  --` #
          ##
 __   __  #
 \ \\/ // #
  \ ` //  #
   | ||   #
   |_||   #
   `-`'   #
          ##
 ______   #
|____ //  #
   / //   #
  / //    #
 / //__   #
/______|| #
`------`  ##
[#
 #
 #
 #
 #
 #
 ##
\#
 #
 #
 #
 #
 #
 ##
]#
 #
 #
 #
 #
 #
 ##
^#
 #
 #
 #
 #
 #
 ##
_#
 #
 #
 #
 #
 #
 ##
`#
 #
 #
 #
 #
 #
 ##
   ___    #
  / _ \\  #
 / //\ \\ #
|  ___  ||#
|_||  |_||#
`-`   `-` #
          ##
 ______   #
|      \\ #
|  --$ // #
|  --  \\ #
|______// #
`------`  #
          ##
  _____   #
 / ____|| #
/ //---`' #
\ \\___   #
 \_____|| #
  `----`  #
          ##
 _____    #
|  __ \\  #
| |$ \ || #
| |__/ || #
|_____//  #
 -----`   #
          ##
  _____   #
 |  ___|| #
 | ||__   #
 | ||__   #
 |_____|| #
 `-----`  #
          ##
  ______  #
 /_____// #
 `____ `  #
 /___//   #
 `__ `    #
 /_//     #
 `-`      ##
  _____   #
 /  ___|| #
| //$__   #
| \\_\ || #
 \____//  #
  `---`   #
          ##
 __   _   #
| || | || #
| '--' || #
| .--. || #
|_|| |_|| #
`-`  `-`  #
          ##
  ______  #
 /_   _// #
  -| ||-  #
  _| ||_  #
 /_____// #
 `-----`  #
          ##
  ______  #
 /_   _// #
   | ||   #
  _| ||   #
 /__//    #
 `--`     #
          ##
  _  __  #
 | |/ // #
 | ' //  #
 | . \\  #
 |_|\_\\ #
 `-` --` #
         ##
  __     #
 | ||    #
 | ||    #
 | ||__  #
 |____// #
 `----`  #
         ##
 _    _   #
| \  / || #
|  \/  || #
| .  . || #
|_|\/|_|| #
`-`  `-`  #
          ##
  _  _   #
 | \| || #
 |  ' || #
 | .  || #
 |_|\_|| #
 `-` -`  #
         ##
   ___    #
  / _ \\  #
 | /$\ || #
 | \_/ || #
  \___//  #
  `---`   #
          ##
          #
  ____    #
 |    \\  #
 | [] ||  #
 |  __//  #
 |_|`-`   #
 `-`      ##
          #
    ___   #
   /   || #
  | [] || #
   \__ || #
    -|_|| #
     `-`  ##
  ____    #
 |  _ \\  #
 | |_| || #
 | .  //  #
 |_|\_\\  #
 `-` --`  #
          ##
   _____  #
  / ___// #
  \___ \\ #
  /  $ // #
 /____//  #
`-----`   #
          ##
  ______  #
 /_   _// #
 `-| |,-  #
   | ||   #
   |_||   #
   `-`'   #
          ##
 _    _   #
| || | || #
| || | || #
| \\_/ || #
 \____//  #
  `---`   #
          ##
__    __  #
\ \\ / // #
 \ \/ //  #
  \  //   #
   \//    #
    `     #
          ##
 _    _   #
| |  | || #
| |/\| || #
|  /\  || #
|_// \_|| #
`-`   `-` #
          ##
 __   __  #
 \ \\/ // #
  \ $ //  #
  / . \\  #
 /_//\_\\ #
 `-`  --` #
          ##
 __   __  #
 \ \\/ // #
  \ ` //  #
   | ||   #
   |_||   #
   `-`'   #
          ##
  _____   #
 |__  //  #
   / //   #
  / //__  #
 /_____|| #
 `-----`  #
          ##
{#
 #
 #
 #
 #
 #
 ##
|#
 #
 #
 #
 #
 #
 ##
}#
 #
 #
 #
 #
 #
 ##
~#
 #
 #
 #
 #
 #
 ##
  []|_[]| #
  / _ \\  #
 / //\ \\ #
| $___$ ||#
|_||$ |_||#
`-`   `-` #
          ##
  []|_[]| #
  / _ \\  #
 | /$\ || #
 | \_/ || #
  \___//  #
   ---`   #
          ##
 []| []|  #
| ||$| || #
| ||$| || #
| \\_/ || #
 \____//  #
  `---`   #
          ##
  []|_[]| #
  / _ \\  #
 / //\ \\ #
| $___$ ||#
|_||$ |_||#
`-`   `-` #
          ##
  []|_[]| #
  / _ \\  #
 | /$\ || #
 | \_/ || #
  \___//  #
   ---`   #
          ##
 []| []|  #
| ||$| || #
| ||$| || #
| \\_/ || #
 \____//  #
  `---`   #
          ##
  ,--.    #
 | _$ \\  #
 |    //  #
 | |\ \\  #
 |$ ___\\ #
 |_|----` #
  -       ##
162  CENT SIGN
   _    #
  | ||  #
 / __// #
| (__`  #
 \   \\ #
  |_|`  #
  `-`  ##
215  MULTIPLICATION SIGN
      #
      #
 \\// #
  \\  #
 //\\ #
      #
      ##


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Text_Exception
 */
require_once 'Zend/Text/Exception.php';

/**
 * Exception class for Zend_Text_Table
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @uses      Zend_Text_Exception
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table_Exception extends Zend_Text_Exception
{
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Row.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Row class for Zend_Text_Table
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table_Row
{
    /**
     * List of all columns
     *
     * @var array
     */
    protected $_columns = array();

    /**
     * Temporary stored column widths
     *
     * @var array
     */
    protected $_columnWidths = null;

    /**
     * Create a new column and append it to the row
     *
     * @param  string $content
     * @param  array  $options
     * @return Zend_Text_Table_Row
     */
    public function createColumn($content, array $options = null)
    {
        $align    = null;
        $colSpan  = null;
        $encoding = null;

        if ($options !== null) {
            extract($options, EXTR_IF_EXISTS);
        }

        require_once 'Zend/Text/Table/Column.php';

        $column = new Zend_Text_Table_Column($content, $align, $colSpan, $encoding);

        $this->appendColumn($column);

        return $this;
    }

    /**
     * Append a column to the row
     *
     * @param  Zend_Text_Table_Column $column The column to append to the row
     * @return Zend_Text_Table_Row
     */
    public function appendColumn(Zend_Text_Table_Column $column)
    {
        $this->_columns[] = $column;

        return $this;
    }

    /**
     * Get a column by it's index
     *
     * Returns null, when the index is out of range
     *
     * @param  integer $index
     * @return Zend_Text_Table_Column|null
     */
    public function getColumn($index)
    {
        if (!isset($this->_columns[$index])) {
            return null;
        }

        return $this->_columns[$index];
    }

    /**
     * Get all columns of the row
     *
     * @return array
     */
    public function getColumns()
    {
        return $this->_columns;
    }

    /**
     * Get the widths of all columns, which were rendered last
     *
     * @throws Zend_Text_Table_Exception When no columns were rendered yet
     * @return integer
     */
    public function getColumnWidths()
    {
        if ($this->_columnWidths === null) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('No columns were rendered yet');
        }

        return $this->_columnWidths;
    }

    /**
     * Render the row
     *
     * @param  array                               $columnWidths Width of all columns
     * @param  Zend_Text_Table_Decorator_Interface $decorator    Decorator for the row borders
     * @param  integer                             $padding      Padding for the columns
     * @throws Zend_Text_Table_Exception When there are too many columns
     * @return string
     */
    public function render(array $columnWidths,
                           Zend_Text_Table_Decorator_Interface $decorator,
                           $padding = 0)
    {
        // Prepare an array to store all column widths
        $this->_columnWidths = array();

        // If there is no single column, create a column which spans over the
        // entire row
        if (count($this->_columns) === 0) {
            require_once 'Zend/Text/Table/Column.php';
            $this->appendColumn(new Zend_Text_Table_Column(null, null, count($columnWidths)));
        }

        // First we have to render all columns, to get the maximum height
        $renderedColumns = array();
        $maxHeight       = 0;
        $colNum          = 0;
        foreach ($this->_columns as $column) {
            // Get the colspan of the column
            $colSpan = $column->getColSpan();

            // Verify if there are enough column widths defined
            if (($colNum + $colSpan) > count($columnWidths)) {
                require_once 'Zend/Text/Table/Exception.php';
                throw new Zend_Text_Table_Exception('Too many columns');
            }

            // Calculate the column width
            $columnWidth = ($colSpan - 1 + array_sum(array_slice($columnWidths,
                                                                 $colNum,
                                                                 $colSpan)));

            // Render the column and split it's lines into an array
            $result = explode("\n", $column->render($columnWidth, $padding));

            // Store the width of the rendered column
            $this->_columnWidths[] = $columnWidth;

            // Store the rendered column and calculate the new max height
            $renderedColumns[] = $result;
            $maxHeight         = max($maxHeight, count($result));

            // Set up the internal column number
            $colNum += $colSpan;
        }

        // If the row doesnt contain enough columns to fill the entire row, fill
        // it with an empty column
        if ($colNum < count($columnWidths)) {
            $remainingWidth = (count($columnWidths) - $colNum - 1) +
                               array_sum(array_slice($columnWidths,
                                                     $colNum));
            $renderedColumns[] = array(str_repeat(' ', $remainingWidth));

            $this->_columnWidths[] = $remainingWidth;
        }

        // Add each single column line to the result
        $result = '';
        for ($line = 0; $line < $maxHeight; $line++) {
            $result .= $decorator->getVertical();

            foreach ($renderedColumns as $renderedColumn) {
                if (isset($renderedColumn[$line]) === true) {
                    $result .= $renderedColumn[$line];
                } else {
                    $result .= str_repeat(' ', strlen($renderedColumn[0]));
                }

                $result .= $decorator->getVertical();
            }

            $result .= "\n";
        }

        return $result;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Column.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Text_Table
 */
require_once 'Zend/Text/Table.php';

/**
 * @see Zend_Text_MultiByte
 */
require_once 'Zend/Text/MultiByte.php';

/**
 * Column class for Zend_Text_Table_Row
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table_Column
{
    /**
     * Aligns for columns
     */
    const ALIGN_LEFT   = 'left';
    const ALIGN_CENTER = 'center';
    const ALIGN_RIGHT  = 'right';

    /**
     * Content of the column
     *
     * @var string
     */
    protected $_content = '';

    /**
     * Align of the column
     *
     * @var string
     */
    protected $_align = self::ALIGN_LEFT;

    /**
     * Colspan of the column
     *
     * @var integer
     */
    protected $_colSpan = 1;

    /**
     * Allowed align parameters
     *
     * @var array
     */
    protected $_allowedAligns = array(self::ALIGN_LEFT, self::ALIGN_CENTER, self::ALIGN_RIGHT);

    /**
     * Create a column for a Zend_Text_Table_Row object.
     *
     * @param string  $content  The content of the column
     * @param string  $align    The align of the content
     * @param integer $colSpan  The colspan of the column
     * @param string  $charset  The encoding of the content
     */
    public function __construct($content = null, $align = null, $colSpan = null, $charset = null)
    {
        if ($content !== null) {
            $this->setContent($content, $charset);
        }

        if ($align !== null) {
            $this->setAlign($align);
        }

        if ($colSpan !== null) {
            $this->setColSpan($colSpan);
        }
    }

    /**
     * Set the content.
     *
     * If $charset is not defined, it is assumed that $content is encoded in
     * the charset defined via Zend_Text_Table::setInputCharset() (defaults
     * to utf-8).
     *
     * @param  string $content  Content of the column
     * @param  string $charset  The charset of the content
     * @throws Zend_Text_Table_Exception When $content is not a string
     * @return Zend_Text_Table_Column
     */
    public function setContent($content, $charset = null)
    {
        if (is_string($content) === false) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('$content must be a string');
        }

        if ($charset === null) {
            $inputCharset = Zend_Text_Table::getInputCharset();
        } else {
            $inputCharset = strtolower($charset);
        }

        $outputCharset = Zend_Text_Table::getOutputCharset();

        if ($inputCharset !== $outputCharset) {
            if (PHP_OS !== 'AIX') {
                // AIX does not understand these character sets
                $content = iconv($inputCharset, $outputCharset, $content);
            }

        }

        $this->_content = $content;

        return $this;
    }

    /**
     * Set the align
     *
     * @param  string $align Align of the column
     * @throws Zend_Text_Table_Exception When supplied align is invalid
     * @return Zend_Text_Table_Column
     */
    public function setAlign($align)
    {
        if (in_array($align, $this->_allowedAligns) === false) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('Invalid align supplied');
        }

        $this->_align = $align;

        return $this;
    }

    /**
     * Set the colspan
     *
     * @param  int $colSpan
     * @throws Zend_Text_Table_Exception When $colSpan is smaller than 1
     * @return Zend_Text_Table_Column
     */
    public function setColSpan($colSpan)
    {
        if (is_int($colSpan) === false or $colSpan < 1) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('$colSpan must be an integer and greater than 0');
        }

        $this->_colSpan = $colSpan;

        return $this;
    }

    /**
     * Get the colspan
     *
     * @return integer
     */
    public function getColSpan()
    {
        return $this->_colSpan;
    }

    /**
     * Render the column width the given column width
     *
     * @param  integer $columnWidth The width of the column
     * @param  integer $padding     The padding for the column
     * @throws Zend_Text_Table_Exception When $columnWidth is lower than 1
     * @throws Zend_Text_Table_Exception When padding is greater than columnWidth
     * @return string
     */
    public function render($columnWidth, $padding = 0)
    {
        if (is_int($columnWidth) === false or $columnWidth < 1) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('$columnWidth must be an integer and greater than 0');
        }

        $columnWidth -= ($padding * 2);

        if ($columnWidth < 1) {
            require_once 'Zend/Text/Table/Exception.php';
            throw new Zend_Text_Table_Exception('Padding (' . $padding . ') is greater than column width');
        }

        switch ($this->_align) {
            case self::ALIGN_LEFT:
                $padMode = STR_PAD_RIGHT;
                break;

            case self::ALIGN_CENTER:
                $padMode = STR_PAD_BOTH;
                break;

            case self::ALIGN_RIGHT:
                $padMode = STR_PAD_LEFT;
                break;

            default:
                // This can never happen, but the CS tells I have to have it ...
                break;
        }

        $outputCharset = Zend_Text_Table::getOutputCharset();
        $lines         = explode("\n", Zend_Text_MultiByte::wordWrap($this->_content, $columnWidth, "\n", true, $outputCharset));
        $paddedLines   = array();

        foreach ($lines AS $line) {
            $paddedLines[] = str_repeat(' ', $padding)
                           . Zend_Text_MultiByte::strPad($line, $columnWidth, ' ', $padMode, $outputCharset)
                           . str_repeat(' ', $padding);
        }

        $result = implode("\n", $paddedLines);

        return $result;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Ascii.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Text_Table_Decorator_Interface
 */
require_once 'Zend/Text/Table/Decorator/Interface.php';

/**
 * ASCII Decorator for Zend_Text_Table
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @uses      Zend_Text_Table_Decorator_Interface
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table_Decorator_Ascii implements Zend_Text_Table_Decorator_Interface
{
    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getTopLeft()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getTopRight()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getBottomLeft()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getBottomRight()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVertical()
    {
        return '|';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontal()
    {
        return '-';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getCross()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVerticalRight()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVerticalLeft()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontalDown()
    {
        return '+';
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontalUp()
    {
        return '+';
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Unicode.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Text_Table_Decorator_Interface
 */
require_once 'Zend/Text/Table/Decorator/Interface.php';

/**
 * Unicode Decorator for Zend_Text_Table
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @uses      Zend_Text_Table_Decorator_Interface
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Text_Table_Decorator_Unicode implements Zend_Text_Table_Decorator_Interface
{
    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getTopLeft()
    {
        return $this->_uniChar(0x250C);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getTopRight()
    {
        return $this->_uniChar(0x2510);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getBottomLeft()
    {
        return $this->_uniChar(0x2514);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getBottomRight()
    {
        return $this->_uniChar(0x2518);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVertical()
    {
        return $this->_uniChar(0x2502);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontal()
    {
        return $this->_uniChar(0x2500);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getCross()
    {
        return $this->_uniChar(0x253C);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVerticalRight()
    {
        return $this->_uniChar(0x251C);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getVerticalLeft()
    {
        return $this->_uniChar(0x2524);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontalDown()
    {
        return $this->_uniChar(0x252C);
    }

    /**
     * Defined by Zend_Text_Table_Decorator_Interface
     *
     * @return string
     */
    public function getHorizontalUp()
    {
        return $this->_uniChar(0x2534);
    }

    /**
     * Convert am unicode character code to a character
     *
     * @param  integer $code
     * @return string|false
     */
    protected function _uniChar($code)
    {
        if ($code <= 0x7F) {
            $char = chr($code);
        } else if ($code <= 0x7FF) {
            $char = chr(0xC0 | $code >> 6)
                  . chr(0x80 | $code & 0x3F);
        } else if ($code <= 0xFFFF) {
            $char =  chr(0xE0 | $code >> 12)
                  . chr(0x80 | $code >> 6 & 0x3F)
                  . chr(0x80 | $code & 0x3F);
        } else if ($code <= 0x10FFFF) {
            $char =  chr(0xF0 | $code >> 18)
                  . chr(0x80 | $code >> 12 & 0x3F)
                  . chr(0x80 | $code >> 6 & 0x3F)
                  . chr(0x80 | $code & 0x3F);
        } else {
            return false;
        }

        return $char;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 * @version   $Id: Interface.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Interface for Zend_Text_Table decorators
 *
 * @category  Zend
 * @package   Zend_Text_Table
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd     New BSD License
 */
interface Zend_Text_Table_Decorator_Interface
{
    /**
     * Get a single character for the top left corner
     *
     * @return string
     */
    public function getTopLeft();

    /**
     * Get a single character for the top right corner
     *
     * @return string
     */
    public function getTopRight();

    /**
     * Get a single character for the bottom left corner
     *
     * @return string
     */
    public function getBottomLeft();

    /**
     * Get a single character for the bottom right corner
     *
     * @return string
     */
    public function getBottomRight();

    /**
     * Get a single character for a vertical line
     *
     * @return string
     */
    public function getVertical();

    /**
     * Get a single character for a horizontal line
     *
     * @return string
     */
    public function getHorizontal();

    /**
     * Get a single character for a crossing line
     *
     * @return string
     */
    public function getCross();

    /**
     * Get a single character for a vertical divider right
     *
     * @return string
     */
    public function getVerticalRight();

    /**
     * Get a single character for a vertical divider left
     *
     * @return string
     */
    public function getVerticalLeft();

    /**
     * Get a single character for a horizontal divider down
     *
     * @return string
     */
    public function getHorizontalDown();

    /**
     * Get a single character for a horizontal divider up
     *
     * @return string
     */
    public function getHorizontalUp();
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Container.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Memory_Container_Interface */
require_once 'Zend/Memory/Container/Interface.php';

/**
 * Memory value container
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Memory_Container implements Zend_Memory_Container_Interface
{
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @version    $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */

/** Zend_Controller_Exception */
require_once 'Zend/Exception.php';

/**
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Memory_Exception extends Zend_Exception
{}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Manager.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Memory_Container_Movable */
require_once 'Zend/Memory/Container/Movable.php';

/** Zend_Memory_Container_Locked */
require_once 'Zend/Memory/Container/Locked.php';

/** Zend_Memory_AccessController */
require_once 'Zend/Memory/AccessController.php';

/**
 * Memory manager
 *
 * This class encapsulates memory menagement operations, when PHP works
 * in limited memory mode.
 *
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Memory_Manager
{
    /**
     * Object storage backend
     *
     * @var Zend_Cache_Backend_Interface
     */
    private $_backend = null;

    /**
     * Memory grow limit.
     * Default value is 2/3 of memory_limit php.ini variable
     * Negative value means no limit
     *
     * @var integer
     */
    private $_memoryLimit = -1;

    /**
     * Minimum value size to be swapped.
     * Default value is 16K
     * Negative value means that memory objects are never swapped
     *
     * @var integer
     */
    private $_minSize = 16384;

    /**
     * Overall size of memory, used by values
     *
     * @var integer
     */
    private $_memorySize = 0;

    /**
     * Id for next Zend_Memory object
     *
     * @var integer
     */
    private $_nextId = 0;

    /**
     * List of candidates to unload
     *
     * It also represents objects access history. Last accessed objects are moved to the end of array
     *
     * array(
     *     <id> => <memory container object>,
     *     ...
     *      )
     *
     * @var array
     */
    private $_unloadCandidates = array();

    /**
     * List of object sizes.
     *
     * This list is used to calculate modification of object sizes
     *
     * array( <id> => <size>, ...)
     *
     * @var array
     */
    private $_sizes = array();

    /**
     * Last modified object
     *
     * It's used to reduce number of calls necessary to trace objects' modifications
     * Modification is not processed by memory manager until we do not switch to another
     * object.
     * So we have to trace only _first_ object modification and do nothing for others
     *
     * @var Zend_Memory_Container_Movable
     */
    private $_lastModified = null;

    /**
     * Unique memory manager id
     *
     * @var integer
     */
    private $_managerId;

    /**
     * Tags array, used by backend to categorize stored values
     *
     * @var array
     */
    private $_tags;

    /**
     * This function is intended to generate unique id, used by memory manager
     */
    private function _generateMemManagerId()
    {
        /**
         * @todo !!!
         * uniqid() php function doesn't really garantee the id to be unique
         * it should be changed by something else
         * (Ex. backend interface should be extended to provide this functionality)
         */
        $this->_managerId = uniqid('ZendMemManager', true);
        $this->_tags = array($this->_managerId);
        $this->_managerId .= '_';
    }

    /**
     * Memory manager constructor
     *
     * If backend is not specified, then memory objects are never swapped
     *
     * @param Zend_Cache_Backend $backend
     * @param array $backendOptions associative array of options for the corresponding backend constructor
     */
    public function __construct($backend = null)
    {
        if ($backend === null) {
            return;
        }

        $this->_backend = $backend;
        $this->_generateMemManagerId();

        $memoryLimitStr = trim(ini_get('memory_limit'));
        if ($memoryLimitStr != ''  &&  $memoryLimitStr != -1) {
            $this->_memoryLimit = (integer)$memoryLimitStr;
            switch (strtolower($memoryLimitStr[strlen($memoryLimitStr)-1])) {
                case 'g':
                    $this->_memoryLimit *= 1024;
                    // Break intentionally omitted
                case 'm':
                    $this->_memoryLimit *= 1024;
                    // Break intentionally omitted
                case 'k':
                    $this->_memoryLimit *= 1024;
                    break;

                default:
                    break;
            }

            $this->_memoryLimit = (int)($this->_memoryLimit*2/3);
        } // No limit otherwise
    }

    /**
     * Object destructor
     *
     * Clean up backend storage
     */
    public function __destruct()
    {
        if ($this->_backend !== null) {
            $this->_backend->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, $this->_tags);
        }
    }

    /**
     * Set memory grow limit
     *
     * @param integer $newLimit
     * @throws Zend_Exception
     */
    public function setMemoryLimit($newLimit)
    {
        $this->_memoryLimit = $newLimit;

        $this->_swapCheck();
    }

    /**
     * Get memory grow limit
     *
     * @return integer
     */
    public function getMemoryLimit()
    {
        return $this->_memoryLimit;
    }

    /**
     * Set minimum size of values, which may be swapped
     *
     * @param integer $newSize
     */
    public function setMinSize($newSize)
    {
        $this->_minSize = $newSize;
    }

    /**
     * Get minimum size of values, which may be swapped
     *
     * @return integer
     */
    public function getMinSize()
    {
        return $this->_minSize;
    }

    /**
     * Create new Zend_Memory value container
     *
     * @param string $value
     * @return Zend_Memory_Container_Interface
     * @throws Zend_Memory_Exception
     */
    public function create($value = '')
    {
        return $this->_create($value,  false);
    }

    /**
     * Create new Zend_Memory value container, which has value always
     * locked in memory
     *
     * @param string $value
     * @return Zend_Memory_Container_Interface
     * @throws Zend_Memory_Exception
     */
    public function createLocked($value = '')
    {
        return $this->_create($value, true);
    }

    /**
     * Create new Zend_Memory object
     *
     * @param string $value
     * @param boolean $locked
     * @return Zend_Memory_Container_Interface
     * @throws Zend_Memory_Exception
     */
    private function _create($value, $locked)
    {
        $id = $this->_nextId++;

        if ($locked  ||  ($this->_backend === null) /* Use only memory locked objects if backend is not specified */) {
            return new Zend_Memory_Container_Locked($value);
        }

        // Commit other objects modifications
        $this->_commit();

        $valueObject = new Zend_Memory_Container_Movable($this, $id, $value);

        // Store last object size as 0
        $this->_sizes[$id] = 0;
        // prepare object for next modifications
        $this->_lastModified = $valueObject;

        return new Zend_Memory_AccessController($valueObject);
    }

    /**
     * Unlink value container from memory manager
     *
     * Used by Memory container destroy() method
     *
     * @internal
     * @param integer $id
     * @return Zend_Memory_Container
     */
    public function unlink(Zend_Memory_Container_Movable $container, $id)
    {
        if ($this->_lastModified === $container) {
            // Drop all object modifications
            $this->_lastModified = null;
            unset($this->_sizes[$id]);
            return;
        }

        if (isset($this->_unloadCandidates[$id])) {
            unset($this->_unloadCandidates[$id]);
        }

        $this->_memorySize -= $this->_sizes[$id];
        unset($this->_sizes[$id]);
    }

    /**
     * Process value update
     *
     * @internal
     * @param Zend_Memory_Container_Movable $container
     * @param integer $id
     */
    public function processUpdate(Zend_Memory_Container_Movable $container, $id)
    {
        /**
         * This method is automatically invoked by memory container only once per
         * "modification session", but user may call memory container touch() method
         * several times depending on used algorithm. So we have to use this check
         * to optimize this case.
         */
        if ($container === $this->_lastModified) {
            return;
        }

        // Remove just updated object from list of candidates to unload
        if( isset($this->_unloadCandidates[$id])) {
            unset($this->_unloadCandidates[$id]);
        }

        // Reduce used memory mark
        $this->_memorySize -= $this->_sizes[$id];

        // Commit changes of previously modified object if necessary
        $this->_commit();

        $this->_lastModified = $container;
    }

    /**
     * Commit modified object and put it back to the loaded objects list
     */
    private function _commit()
    {
        if (($container = $this->_lastModified) === null) {
            return;
        }

        $this->_lastModified = null;

        $id = $container->getId();

        // Calculate new object size and increase used memory size by this value
        $this->_memorySize += ($this->_sizes[$id] = strlen($container->getRef()));

        if ($this->_sizes[$id] > $this->_minSize) {
            // Move object to "unload candidates list"
            $this->_unloadCandidates[$id] = $container;
        }

        $container->startTrace();

        $this->_swapCheck();
    }

    /**
     * Check and swap objects if necessary
     *
     * @throws Zend_MemoryException
     */
    private function _swapCheck()
    {
        if ($this->_memoryLimit < 0  ||  $this->_memorySize < $this->_memoryLimit) {
            // Memory limit is not reached
            // Do nothing
            return;
        }

        // walk through loaded objects in access history order
        foreach ($this->_unloadCandidates as $id => $container) {
            $this->_swap($container, $id);
            unset($this->_unloadCandidates[$id]);

            if ($this->_memorySize < $this->_memoryLimit) {
                // We've swapped enough objects
                return;
            }
        }

        require_once 'Zend/Memory/Exception.php';
        throw new Zend_Memory_Exception('Memory manager can\'t get enough space.');
    }

    /**
     * Swap object data to disk
     * Actualy swaps data or only unloads it from memory,
     * if object is not changed since last swap
     *
     * @param Zend_Memory_Container_Movable $container
     * @param integer $id
     */
    private function _swap(Zend_Memory_Container_Movable $container, $id)
    {
        if ($container->isLocked()) {
            return;
        }

        if (!$container->isSwapped()) {
            $this->_backend->save($container->getRef(), $this->_managerId . $id, $this->_tags);
        }

        $this->_memorySize -= $this->_sizes[$id];

        $container->markAsSwapped();
        $container->unloadValue();
    }

    /**
     * Load value from swap file.
     *
     * @internal
     * @param Zend_Memory_Container_Movable $container
     * @param integer $id
     */
    public function load(Zend_Memory_Container_Movable $container, $id)
    {
        $value = $this->_backend->load($this->_managerId . $id, true);

        // Try to swap other objects if necessary
        // (do not include specified object into check)
        $this->_memorySize += strlen($value);
        $this->_swapCheck();

        // Add loaded obect to the end of loaded objects list
        $container->setValue($value);

        if ($this->_sizes[$id] > $this->_minSize) {
            // Add object to the end of "unload candidates list"
            $this->_unloadCandidates[$id] = $container;
        }
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: AccessController.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Zend_Memory_Container_Interface
 */
require_once 'Zend/Memory/Container/Interface.php';

/**
 * Memory object container access controller.
 *
 * Memory manager stores a list of generated objects to control them.
 * So container objects always have at least one reference and can't be automatically destroyed.
 *
 * This class is intended to be an userland proxy to memory container object.
 * It's not referenced by memory manager and class destructor is invoked immidiately after gouing
 * out of scope or unset operation.
 *
 * Class also provides Zend_Memory_Container_Interface interface and works as proxy for such cases.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Memory_AccessController implements Zend_Memory_Container_Interface
{
    /**
     * Memory container object
     *
     * @var Zend_Memory_Container
     */
    private $_memContainer;

    /**
     * Object constructor
     *
     * @param Zend_Memory_Container_Movable $memoryManager
     */
    public function __construct(Zend_Memory_Container_Movable $memContainer)
    {
        $this->_memContainer = $memContainer;
    }

    /**
     * Object destructor
     */
    public function __destruct()
    {
        $this->_memContainer->destroy();
    }

    /**
     * Get string value reference
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @return &string
     */
    public function &getRef()
    {
        return $this->_memContainer->getRef();
    }

    /**
     * Signal, that value is updated by external code.
     *
     * Should be used together with getRef()
     */
    public function touch()
    {
        $this->_memContainer->touch();
    }

    /**
     * Lock object in memory.
     */
    public function lock()
    {
        $this->_memContainer->lock();
    }

    /**
     * Unlock object
     */
    public function unlock()
    {
        $this->_memContainer->unlock();
    }

    /**
     * Return true if object is locked
     *
     * @return boolean
     */
    public function isLocked()
    {
        return $this->_memContainer->isLocked();
    }

    /**
     * Get handler
     *
     * Loads object if necessary and moves it to the top of loaded objects list.
     * Swaps objects from the bottom of loaded objects list, if necessary.
     *
     * @param string $property
     * @return string
     * @throws Zend_Memory_Exception
     */
    public function __get($property)
    {
        return $this->_memContainer->$property;
    }

    /**
     * Set handler
     *
     * @param string $property
     * @param  string $value
     * @throws Zend_Exception
     */
    public function __set($property, $value)
    {
        $this->_memContainer->$property = $value;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Value.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * String value object
 *
 * It's an OO string wrapper.
 * Used to intercept string updates.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @todo       also implement Countable for PHP 5.1 but not yet to stay 5.0 compatible
 */
class Zend_Memory_Value implements ArrayAccess {
    /**
     * Value
     *
     * @var string
     */
    private $_value;

    /**
     * Container
     *
     * @var Zend_Memory_Container_Interface
     */
    private $_container;

    /**
     * Boolean flag which signals to trace value modifications
     *
     * @var boolean
     */
    private $_trace;

    /**
     * Object constructor
     *
     * @param string $value
     * @param Zend_Memory_Container_Movable $container
     */
    public function __construct($value, Zend_Memory_Container_Movable $container)
    {
        $this->_container = $container;

        $this->_value = (string)$value;

        /**
         * Object is marked as just modified by memory manager
         * So we don't need to trace followed object modifications and
         * object is processed (and marked as traced) when another
         * memory object is modified.
         *
         * It reduces overall numberr of calls necessary to modification trace
         */
        $this->_trace = false;
    }

    /**
     * ArrayAccess interface method
     * returns true if string offset exists
     *
     * @param integer $offset
     * @return boolean
     */
    public function offsetExists($offset)
    {
        return $offset >= 0  &&  $offset < strlen($this->_value);
    }

    /**
     * ArrayAccess interface method
     * Get character at $offset position
     *
     * @param integer $offset
     * @return string
     */
    public function offsetGet($offset)
    {
        return $this->_value[$offset];
    }

    /**
     * ArrayAccess interface method
     * Set character at $offset position
     *
     * @param integer $offset
     * @param string $char
     */
    public function offsetSet($offset, $char)
    {
        $this->_value[$offset] = $char;

        if ($this->_trace) {
            $this->_trace = false;
            $this->_container->processUpdate();
        }
    }

    /**
     * ArrayAccess interface method
     * Unset character at $offset position
     *
     * @param integer $offset
     */
    public function offsetUnset($offset)
    {
        unset($this->_value[$offset]);

        if ($this->_trace) {
            $this->_trace = false;
            $this->_container->processUpdate();
        }
    }

    /**
     * To string conversion
     *
     * @return string
     */
    public function __toString()
    {
        return $this->_value;
    }

    /**
     * Get string value reference
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @internal
     * @return string
     */
    public function &getRef()
    {
        return $this->_value;
    }

    /**
     * Start modifications trace
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @internal
     */
    public function startTrace()
    {
        $this->_trace = true;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Movable.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Memory_Container */
require_once 'Zend/Memory/Container.php';

/** Zend_Memory_Value */
require_once 'Zend/Memory/Value.php';

/**
 * Memory value container
 *
 * Movable (may be swapped with specified backend and unloaded).
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Memory_Container_Movable extends Zend_Memory_Container {
    /**
     * Internal object Id
     *
     * @var integer
     */
    protected $_id;

    /**
     * Memory manager reference
     *
     * @var Zend_Memory_Manager
     */
    private $_memManager;

    /**
     * Value object
     *
     * @var Zend_Memory_Value
     */
    private $_value;

    /** Value states */
    const LOADED   = 1;
    const SWAPPED  = 2;
    const LOCKED   = 4;

    /**
     * Value state (LOADED/SWAPPED/LOCKED)
     *
     * @var integer
     */
    private $_state;

    /**
     * Object constructor
     *
     * @param Zend_Memory_Manager $memoryManager
     * @param integer $id
     * @param string $value
     */
    public function __construct(Zend_Memory_Manager $memoryManager, $id, $value)
    {
        $this->_memManager = $memoryManager;
        $this->_id    = $id;
        $this->_state = self::LOADED;
        $this->_value = new Zend_Memory_Value($value, $this);
    }

    /**
     * Lock object in memory.
     */
    public function lock()
    {
        if ( !($this->_state & self::LOADED) ) {
            $this->_memManager->load($this, $this->_id);
            $this->_state |= self::LOADED;
        }

        $this->_state |= self::LOCKED;

        /**
         * @todo
         * It's possible to set "value" container attribute to avoid modification tracing, while it's locked
         * Check, if it's  more effective
         */
    }

    /**
     * Unlock object
     */
    public function unlock()
    {
        // Clear LOCKED state bit
        $this->_state &= ~self::LOCKED;
    }

    /**
     * Return true if object is locked
     *
     * @return boolean
     */
    public function isLocked()
    {
        return $this->_state & self::LOCKED;
    }

    /**
     * Get handler
     *
     * Loads object if necessary and moves it to the top of loaded objects list.
     * Swaps objects from the bottom of loaded objects list, if necessary.
     *
     * @param string $property
     * @return string
     * @throws Zend_Memory_Exception
     */
    public function __get($property)
    {
        if ($property != 'value') {
            require_once 'Zend/Memory/Exception.php';
            throw new Zend_Memory_Exception('Unknown property: Zend_Memory_container::$' . $property);
        }

        if ( !($this->_state & self::LOADED) ) {
            $this->_memManager->load($this, $this->_id);
            $this->_state |= self::LOADED;
        }

        return $this->_value;
    }

    /**
     * Set handler
     *
     * @param string $property
     * @param  string $value
     * @throws Zend_Exception
     */
    public function __set($property, $value)
    {
        if ($property != 'value') {
            require_once 'Zend/Memory/Exception.php';
            throw new Zend_Memory_Exception('Unknown property: Zend_Memory_container::$' . $property);
        }

        $this->_state = self::LOADED;
        $this->_value = new Zend_Memory_Value($value, $this);

        $this->_memManager->processUpdate($this, $this->_id);
    }

    /**
     * Get string value reference
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @return &string
     */
    public function &getRef()
    {
        if ( !($this->_state & self::LOADED) ) {
            $this->_memManager->load($this, $this->_id);
            $this->_state |= self::LOADED;
        }

        return $this->_value->getRef();
    }

    /**
     * Signal, that value is updated by external code.
     *
     * Should be used together with getRef()
     */
    public function touch()
    {
        $this->_memManager->processUpdate($this, $this->_id);
    }

    /**
     * Process container value update.
     * Must be called only by value object
     *
     * @internal
     */
    public function processUpdate()
    {
        // Clear SWAPPED state bit
        $this->_state &= ~self::SWAPPED;

        $this->_memManager->processUpdate($this, $this->_id);
    }

    /**
     * Start modifications trace
     *
     * @internal
     */
    public function startTrace()
    {
        if ( !($this->_state & self::LOADED) ) {
            $this->_memManager->load($this, $this->_id);
            $this->_state |= self::LOADED;
        }

        $this->_value->startTrace();
    }

    /**
     * Set value (used by memory manager when value is loaded)
     *
     * @internal
     */
    public function setValue($value)
    {
        $this->_value = new Zend_Memory_Value($value, $this);
    }

    /**
     * Clear value (used by memory manager when value is swapped)
     *
     * @internal
     */
    public function unloadValue()
    {
        // Clear LOADED state bit
        $this->_state &= ~self::LOADED;

        $this->_value = null;
    }

    /**
     * Mark, that object is swapped
     *
     * @internal
     */
    public function markAsSwapped()
    {
        // Clear LOADED state bit
        $this->_state |= self::LOADED;
    }

    /**
     * Check if object is marked as swapped
     *
     * @internal
     * @return boolean
     */
    public function isSwapped()
    {
        return $this->_state & self::SWAPPED;
    }

    /**
     * Get object id
     *
     * @internal
     * @return integer
     */
    public function getId()
    {
        return $this->_id;
    }
    /**
     * Destroy memory container and remove it from memory manager list
     *
     * @internal
     */
    public function destroy()
    {
        /**
         * We don't clean up swap because of performance considerations
         * Cleaning is performed by Memory Manager destructor
         */

        $this->_memManager->unlink($this, $this->_id);
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Interface.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Memory value container interface
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
interface Zend_Memory_Container_Interface
{
    /**
     * Get string value reference
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @return &string
     */
    public function &getRef();

    /**
     * Signal, that value is updated by external code.
     *
     * Should be used together with getRef()
     */
    public function touch();

    /**
     * Lock object in memory.
     */
    public function lock();

    /**
     * Unlock object
     */
    public function unlock();

    /**
     * Return true if object is locked
     *
     * @return boolean
     */
    public function isLocked();
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Locked.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Memory_Container */
require_once 'Zend/Memory/Container.php';

/**
 * Memory value container
 *
 * Locked (always stored in memory).
 *
 * @category   Zend
 * @package    Zend_Memory
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Memory_Container_Locked extends Zend_Memory_Container
{
    /**
     * Value object
     *
     * @var string
     */
    public $value;

    /**
     * Object constructor
     *
     * @param Zend_Memory_Manager $memoryManager
     * @param integer $id
     * @param string $value
     */
    public function __construct($value)
    {
        $this->value = $value;
    }

    /**
     * Lock object in memory.
     */
    public function lock()
    {
        /* Do nothing */
    }

    /**
     * Unlock object
     */
    public function unlock()
    {
        /* Do nothing */
    }

    /**
     * Return true if object is locked
     *
     * @return boolean
     */
    public function isLocked()
    {
        return true;
    }

    /**
     * Get string value reference
     *
     * _Must_ be used for value access before PHP v 5.2
     * or _may_ be used for performance considerations
     *
     * @return &string
     */
    public function &getRef()
    {
        return $this->value;
    }

    /**
     * Signal, that value is updated by external code.
     *
     * Should be used together with getRef()
     */
    public function touch()
    {
        /* Do nothing */
    }

    /**
     * Destroy memory container and remove it from memory manager list
     */
    public function destroy()
    {
        /* Do nothing */
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Markup
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Exception
 */
require_once 'Zend/Exception.php';

/**
 * Exception class for Zend_Markup
 *
 * @category   Zend
 * @uses       Zend_Exception
 * @package    Zend_Markup
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Markup_Exception extends Zend_Exception
{
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Markup
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: TokenList.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Markup_Token
 */
require_once 'Zend/Markup/Token.php';

/**
 * @category   Zend
 * @package    Zend_Markup
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Markup_TokenList implements RecursiveIterator
{

    /**
     * Array of tokens
     *
     * @var array
     */
    protected $_tokens = array();

    /**
     * Get the current token
     *
     * @return Zend_Markup_Token
     */
    public function current()
    {
        return current($this->_tokens);
    }

    /**
     * Get the children of the current token
     *
     * @return Zend_Markup_TokenList
     */
    public function getChildren()
    {
        return current($this->_tokens)->getChildren();
    }

    /**
     * Add a new child token
     *
     * @param Zend_Markup_Token $child
     *
     * @return void
     */
    public function addChild(Zend_Markup_Token $child)
    {
        $this->_tokens[] = $child;
    }

    /**
     * Check if the current token has children
     *
     * @return bool
     */
    public function hasChildren()
    {
        return current($this->_tokens)->hasChildren();
    }

    /**
     * Get the key of the current token
     *
     * @return int
     */
    public function key()
    {
        return key($this->_tokens);
    }

    /**
     * Go to the next token
     *
     * @return Zend_Markup_Token
     */
    public function next()
    {
        return next($this->_tokens);
    }

    /**
     * Rewind the iterator
     *
     * @return void
     */
    public function rewind()
    {
        reset($this->_tokens);
    }

    /**
     * Check if the element is valid
     *
     * @return void
     */
    public function valid()
    {
        return $this->current() !== false;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Markup
 * @subpackage Parser
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Token.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @see Zend_Markup_TokenList
 */
require_once 'Zend/Markup/TokenList.php';

/**
 * @category   Zend
 * @package    Zend_Markup
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Markup_Token
{
    const TYPE_NONE    = 'none';
    const TYPE_TAG     = 'tag';

    /**
     * Children of this token
     *
     * @var Zend_Markup_TokenList
     */
    protected $_children;

    /**
     * The complete tag
     *
     * @var string
     */
    protected $_tag;

    /**
     * The tag's type
     *
     * @var string
     */
    protected $_type;

    /**
     * Tag name
     *
     * @var string
     */
    protected $_name = '';

    /**
     * Tag attributes
     *
     * @var array
     */
    protected $_attributes = array();

    /**
     * The used tag stopper (empty when none is found)
     *
     * @var string
     */
    protected $_stopper = '';

    /**
     * The parent token
     *
     * @var Zend_Markup_Token
     */
    protected $_parent;

    /**
     * Construct the token
     *
     * @param  string $tag
     * @param  string $type
     * @param  string $name
     * @param  array $attributes
     * @param  Zend_Markup_Token $parent
     * @return void
     */
    public function __construct(
        $tag,
        $type,
        $name = '',
        array $attributes = array(),
        Zend_Markup_Token $parent = null
    ) {
        $this->_tag        = $tag;
        $this->_type       = $type;
        $this->_name       = $name;
        $this->_attributes = $attributes;
        $this->_parent     = $parent;
    }

    // accessors

    /**
     * Set the stopper
     *
     * @param string $stopper
     * @return Zend_Markup_Token
     */
    public function setStopper($stopper)
    {
        $this->_stopper = $stopper;

        return $this;
    }

    /**
     * Get the stopper
     *
     * @return string
     */
    public function getStopper()
    {
        return $this->_stopper;
    }

    /**
     * Get the token's name
     *
     * @return string
     */
    public function getName()
    {
        return $this->_name;
    }

    /**
     * Get the token's type
     *
     * @return string
     */
    public function getType()
    {
        return $this->_type;
    }

    /**
     * Get the complete tag
     *
     * @return string
     */
    public function getTag()
    {
        return $this->_tag;
    }

    /**
     * Get an attribute
     *
     * @param string $name
     *
     * @return string
     */
    public function getAttribute($name)
    {
        return isset($this->_attributes[$name]) ? $this->_attributes[$name] : null;
    }

    /**
     * Check if the token has an attribute
     *
     * @param string $name
     *
     * @return bool
     */
    public function hasAttribute($name)
    {
        return isset($this->_attributes[$name]);
    }

    /**
     * Get all the attributes
     *
     * @return array
     */
    public function getAttributes()
    {
        return $this->_attributes;
    }

    /**
     * Add an attribute
     *
     * @return Zend_Markup_Token
     */
    public function addAttribute($name, $value)
    {
        $this->_attributes[$name] = $value;

        return $this;
    }

    /**
     * Check if an attribute is empty
     *
     * @param string $name
     *
     * @return bool
     */
    public function attributeIsEmpty($name)
    {
        return empty($this->_attributes[$name]);
    }

    // functions for child/parent tokens

    /**
     * Add a child token
     *
     * @return void
     */
    public function addChild(Zend_Markup_Token $child)
    {
        $this->getChildren()->addChild($child);
    }

    /**
     * Set the children token list
     *
     * @param  Zend_Markup_TokenList $children
     * @return Zend_Markup_Token
     */
    public function setChildren(Zend_Markup_TokenList $children)
    {
        $this->_children = $children;
        return $this;
    }

    /**
     * Get the children for this token
     *
     * @return Zend_Markup_TokenList
     */
    public function getChildren()
    {
        if (null === $this->_children) {
            $this->setChildren(new Zend_Markup_TokenList());
        }
        return $this->_children;
    }

    /**
     * Does this token have any children
     *
     * @return bool
     */
    public function hasChildren()
    {
        return !empty($this->_children);
    }

    /**
     * Get the parent token (if any)
     *
     * @return Zend_Markup_Token
     */
    public function getParent()
    {
        return $this->_parent;
    }

    /**
     * Set a parent token
     *
     * @param  Zend_Markup_Token $parent
     * @return Zend_Markup_Token
     */
    public function setParent(Zend_Markup_Token $parent)
    {
        $this->_parent = $parent;
        return $this;
    }

    /**
     * Magic clone function
     *
     * @return void
     */
    public function __clone()
    {
        $this->_parent   = null;
        $this->_children = null;
        $this->_tag      = '';
    }
}