* @version $Revision: 419 $ * @date $Date: 2006-02-20 17:22:36 +0100 (Mon, 20 Feb 2006) $ * @license http://www.gnu.org/licenses/gpl.html GNU General Public * License (GPL) * @package PEL */ /**#@+ Required class definitions. */ require_once('PelException.php'); require_once('PelEntry.php'); /**#@-*/ /** * Exception cast when numbers overflow. * * @author Martin Geisler * @package PEL * @subpackage Exception */ class PelOverflowException extends PelException { /** * Construct a new overflow exception. * * @param int the value that is out of range. * * @param int the minimum allowed value. * * @param int the maximum allowed value. */ function __construct($v, $min, $max) { parent::__construct('Value %.0f out of range [%.0f, %.0f]', $v, $min, $max); } } /** * Class for holding numbers. * * This class can hold numbers, with range checks. * * @author Martin Geisler * @package PEL */ abstract class PelEntryNumber extends PelEntry { /** * The value held by this entry. * * @var array */ protected $value = array(); /** * The minimum allowed value. * * Any attempt to change the value below this variable will result * in a {@link PelOverflowException} being thrown. * * @var int */ protected $min; /** * The maximum allowed value. * * Any attempt to change the value over this variable will result in * a {@link PelOverflowException} being thrown. * * @var int */ protected $max; /** * The dimension of the number held. * * Normal numbers have a dimension of one, pairs have a dimension of * two, etc. * * @var int */ protected $dimension = 1; /** * Change the value. * * This method can change both the number of components and the * value of the components. Range checks will be made on the new * value, and a {@link PelOverflowException} will be thrown if the * value is found to be outside the legal range. * * The method accept several number arguments. The {@link getValue} * method will always return an array except for when a single * number is given here. * * @param int|array $value... the new value(s). This can be zero or * more numbers, that is, either integers or arrays. The input will * be checked to ensure that the numbers are within the valid range. * If not, then a {@link PelOverflowException} will be thrown. * * @see getValue */ function setValue(/* $value... */) { $value = func_get_args(); $this->setValueArray($value); } /** * Change the value. * * This method can change both the number of components and the * value of the components. Range checks will be made on the new * value, and a {@link PelOverflowException} will be thrown if the * value is found to be outside the legal range. * * @param array the new values. The array must contain the new * numbers. * * @see getValue */ function setValueArray($value) { foreach ($value as $v) $this->validateNumber($v); $this->components = count($value); $this->value = $value; } /** * Return the numeric value held. * * @return int|array this will either be a single number if there is * only one component, or an array of numbers otherwise. */ function getValue() { if ($this->components == 1) return $this->value[0]; else return $this->value; } /** * Validate a number. * * This method will check that the number given is within the range * given my {@link getMin()} and {@link getMax()}, inclusive. If * not, then a {@link PelOverflowException} is thrown. * * @param int|array the number in question. * * @return void nothing, but will throw a {@link * PelOverflowException} if the number is found to be outside the * legal range and {@link Pel::$strict} is true. */ function validateNumber($n) { if ($this->dimension == 1) { if ($n < $this->min || $n > $this->max) Pel::maybeThrow(new PelOverflowException($n, $this->min, $this->max)); } else { for ($i = 0; $i < $this->dimension; $i++) if ($n[$i] < $this->min || $n[$i] > $this->max) Pel::maybeThrow(new PelOverflowException($n[$i], $this->min, $this->max)); } } /** * Add a number. * * This appends a number to the numbers already held by this entry, * thereby increasing the number of components by one. * * @param int|array the number to be added. */ function addNumber($n) { $this->validateNumber($n); $this->value[] = $n; $this->components++; } /** * Convert a number into bytes. * * The concrete subclasses will have to implement this method so * that the numbers represented can be turned into bytes. * * The method will be called once for each number held by the entry. * * @param int the number that should be converted. * * @param PelByteOrder one of {@link PelConvert::LITTLE_ENDIAN} and * {@link PelConvert::BIG_ENDIAN}, specifying the target byte order. * * @return string bytes representing the number given. */ abstract function numberToBytes($number, $order); /** * Turn this entry into bytes. * * @param PelByteOrder the desired byte order, which must be either * {@link PelConvert::LITTLE_ENDIAN} or {@link * PelConvert::BIG_ENDIAN}. * * @return string bytes representing this entry. */ function getBytes($o) { $bytes = ''; for ($i = 0; $i < $this->components; $i++) { if ($this->dimension == 1) { $bytes .= $this->numberToBytes($this->value[$i], $o); } else { for ($j = 0; $j < $this->dimension; $j++) { $bytes .= $this->numberToBytes($this->value[$i][$j], $o); } } } return $bytes; } /** * Format a number. * * This method is called by {@link getText} to format numbers. * Subclasses should override this method if they need more * sophisticated behavior than the default, which is to just return * the number as is. * * @param int the number which will be formatted. * * @param boolean it could be that there is both a verbose and a * brief formatting available, and this argument controls that. * * @return string the number formatted as a string suitable for * display. */ function formatNumber($number, $brief = false) { return $number; } /** * Get the numeric value of this entry as text. * * @param boolean use brief output? The numbers will be separated * by a single space if brief output is requested, otherwise a space * and a comma will be used. * * @return string the numbers(s) held by this entry. */ function getText($brief = false) { if ($this->components == 0) return ''; $str = $this->formatNumber($this->value[0]); for ($i = 1; $i < $this->components; $i++) { $str .= ($brief ? ' ' : ', '); $str .= $this->formatNumber($this->value[$i]); } return $str; } } ?>