myaac/system/libs/pot/OTS_Buffer.php
2017-05-01 20:05:36 +02:00

422 lines
9.3 KiB
PHP

<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Binary buffer container.
*
* <p>
* This is generic class for classes that uses buffer-baser read-write operations (it can also emulate C-like pointers).
* <p>
*
* <p>
* Note that unlike <var>NetworkMessage</var> class from OTServ C++ source code, in this one reading and writing positions are separated so you can pararelly read and write it's content like for example using object of this class as stack.
* </p>
*
* @package POT
* @version 0.1.3
* @property string $buffer Properties binary string.
* @property int $char {@link OTS_Buffer::getChar() getChar()}/{@link OTS_Buffer::putChar() putChar()} method wrapper.
* @property int $short {@link OTS_Buffer::getShort() getShort()}/{@link OTS_Buffer::putShort() putShort()} method wrapper.
* @property int $long {@link OTS_Buffer::getLong() getLong()}/{@link OTS_Buffer::putLong() putLong()} method wrapper.
* @property string $string {@link OTS_Buffer::getString() getString(false)}/{@link OTS_Buffer::putString() putString(, true)} call wrapper.
* @property int $pos {@link OTS_Buffer::getPos() getPos()}/{@link OTS_Buffer::setPos() setPos()} method wrapper.
* @property-read bool $valid {@link OTS_Buffer::isValid() isValid()} method wrapper.
* @property-read int $size {@link OTS_Buffer::getSize() getSize()} method wrapper.
*/
class OTS_Buffer
{
/**
* Node properties stream.
*
* @var string
*/
protected $buffer;
/**
* Properties stream pointer.
*
* @var int
*/
protected $pos;
/**
* Initializes new buffered reader.
*
* @param string $buffer Buffer content.
*/
public function __construct($buffer = '')
{
$this->buffer = $buffer;
$this->pos = 0;
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Returs properties stream.
*
* @return string Properties stream.
*/
public function getBuffer()
{
return $this->buffer;
}
/**
* Sets properties stream.
*
* @param string Properties stream.
*/
public function setBuffer($buffer)
{
$this->buffer = $buffer;
$this->pos = 0;
}
/**
* Checks if there is anything left in stream.
*
* @return bool False if pointer is at the end of stream.
*/
public function isValid()
{
return $this->pos < strlen($this->buffer);
}
/**
* Checks stream end state.
*
* @param int $size Amount of bytes that are going to be read.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
protected function check($size = 1)
{
if( strlen($this->buffer) < $this->pos + $size)
{
throw new E_OTS_OutOfBuffer();
}
}
/**
* Returns single byte.
*
* @return int Byte (char) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getChar()
{
// checks buffer size
$this->check();
$value = ord($this->buffer[$this->pos]);
$this->pos++;
return $value;
}
/**
* Appends single byte to buffer.
*
* @param int $char Byte (char) value.
*/
public function putChar($char)
{
$this->buffer .= chr($char);
}
/**
* Returns double byte.
*
* @return int Word (short) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getShort()
{
// checks buffer size
$this->check(2);
$value = unpack('v', substr($this->buffer, $this->pos, 2) );
$this->pos += 2;
return $value[1];
}
/**
* Appends double byte to buffer.
*
* @param int $short Word (short) value.
*/
public function putShort($short)
{
$this->buffer .= pack('v', $short);
}
/**
* Returns quater byte.
*
* @return int Double word (long) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getLong()
{
// checks buffer size
$this->check(4);
$value = unpack('V', substr($this->buffer, $this->pos, 4) );
$this->pos += 4;
return $value[1];
}
/**
* Appends quater byte to buffer.
*
* @param int $long Double word (long) value.
*/
public function putLong($long)
{
$this->buffer .= pack('V', $long);
}
/**
* Returns string from buffer.
*
* <p>
* If length is not given then treats first short value from current buffer as string length.
* </p>
*
* @param int|bool $length String length.
* @return string First substring.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getString($length = false)
{
// reads string length if not given
if($length === false)
{
$length = $this->getShort();
}
// checks buffer size
$this->check($length);
// copies substring
$value = substr($this->buffer, $this->pos, $length);
$this->pos += $length;
return $value;
}
/**
* Appends string to buffer.
*
* @param string $string Binary length.
* @param bool $dynamic Whether if string length is fixed or not (if it is dynamic then length will be inserted as short before string chunk).
*/
public function putString($string, $dynamic = true)
{
// appends string length if requires
if($dynamic)
{
$this->putShort( strlen($string) );
}
$this->buffer .= $string;
}
/**
* Empties buffer.
*/
public function reset()
{
$this->__construct();
}
/**
* Returns current read position.
*
* @return int Read position.
*/
public function getPos()
{
return $this->pos;
}
/**
* Seeks current reading position.
*
* @param int $pos Read position.
*/
public function setPos($pos)
{
$this->pos = $pos;
}
/**
* Returns buffer size.
*
* @return int Buffer length.
*/
public function getSize()
{
return strlen($this->buffer);
}
/**
* Skips given amount of bytes.
*
* @param int $n Bytes to skip.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function skip($n)
{
$this->check($n);
$this->pos += $n;
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function __get($name)
{
switch($name)
{
// simple properties
case 'buffer':
return $this->buffer;
// isValid() wrapper
case 'valid':
return $this->isValid();
// getChar() wrapper
case 'char':
return $this->getChar();
// getShort() wrapper
case 'short':
return $this->getShort();
// getLong() wrapper
case 'long':
return $this->getLong();
// getString() wrapper
case 'string':
return $this->getString();
// getPos() wrapper
case 'pos':
return $this->getPos();
// getSize() wrapper
case 'size':
return $this->getSize();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.3
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
// buffer needs to be reset
case 'buffer':
$this->setBuffer($value);
break;
// putChar() wrapper
case 'char':
$this->putChar($value);
break;
// putShort() wrapper
case 'short':
$this->putShort($value);
break;
// putLong() wrapper
case 'long':
$this->putLong($value);
break;
// putString() wrapper
case 'string':
$this->putString($value);
break;
// setPos() wrapper
case 'pos':
$this->setPos($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of buffer object.
*
* @return string Object's buffer.
*/
public function __toString()
{
return $this->buffer;
}
/**
* Resets pointer of cloned object.
*/
public function __clone()
{
$this->pos = 0;
}
}
/**#@-*/
?>