280 lines
7 KiB
PHP
280 lines
7 KiB
PHP
|
<?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_Amf
|
||
|
* @subpackage Util
|
||
|
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||
|
* @version $Id: BinaryStream.php 16971 2009-07-22 18:05:45Z mikaelkael $
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Utility class to walk through a data stream byte by byte with conventional names
|
||
|
*
|
||
|
* @package Zend_Amf
|
||
|
* @subpackage Util
|
||
|
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
||
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
||
|
*/
|
||
|
class Zend_Amf_Util_BinaryStream
|
||
|
{
|
||
|
/**
|
||
|
* @var string Byte stream
|
||
|
*/
|
||
|
protected $_stream;
|
||
|
|
||
|
/**
|
||
|
* @var int Length of stream
|
||
|
*/
|
||
|
protected $_streamLength;
|
||
|
|
||
|
/**
|
||
|
* @var bool BigEndian encoding?
|
||
|
*/
|
||
|
protected $_bigEndian;
|
||
|
|
||
|
/**
|
||
|
* @var int Current position in stream
|
||
|
*/
|
||
|
protected $_needle;
|
||
|
|
||
|
/**
|
||
|
* Constructor
|
||
|
*
|
||
|
* Create a refrence to a byte stream that is going to be parsed or created
|
||
|
* by the methods in the class. Detect if the class should use big or
|
||
|
* little Endian encoding.
|
||
|
*
|
||
|
* @param string $stream use '' if creating a new stream or pass a string if reading.
|
||
|
* @return void
|
||
|
*/
|
||
|
public function __construct($stream)
|
||
|
{
|
||
|
if (!is_string($stream)) {
|
||
|
require_once 'Zend/Amf/Exception.php';
|
||
|
throw new Zend_Amf_Exception('Inputdata is not of type String');
|
||
|
}
|
||
|
|
||
|
$this->_stream = $stream;
|
||
|
$this->_needle = 0;
|
||
|
$this->_streamLength = strlen($stream);
|
||
|
$testEndian = unpack("C*", pack("S*", 256));
|
||
|
$this->_bigEndian = 1;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the current stream
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getStream()
|
||
|
{
|
||
|
return $this->_stream;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Read the number of bytes in a row for the length supplied.
|
||
|
*
|
||
|
* @todo Should check that there are enough bytes left in the stream we are about to read.
|
||
|
* @param int $length
|
||
|
* @return string
|
||
|
* @throws Zend_Amf_Exception for buffer underrun
|
||
|
*/
|
||
|
public function readBytes($length)
|
||
|
{
|
||
|
if (($length + $this->_needle) > strlen($this->_stream)) {
|
||
|
require_once 'Zend/Amf/Exception.php';
|
||
|
throw new Zend_Amf_Exception("Buffer underrun at needle position: " . $this->_needle . " while requesting length: " . $length);
|
||
|
}
|
||
|
$bytes = substr($this->_stream, $this->_needle, $length);
|
||
|
$this->_needle += $length;
|
||
|
return $bytes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write any length of bytes to the stream
|
||
|
*
|
||
|
* Usually a string.
|
||
|
*
|
||
|
* @param string $bytes
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeBytes($bytes)
|
||
|
{
|
||
|
$this->_stream .= $bytes;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads a signed byte
|
||
|
*
|
||
|
* @return int Value is in the range of -128 to 127.
|
||
|
*/
|
||
|
public function readByte()
|
||
|
{
|
||
|
$byte = ord($this->_stream[$this->_needle++]);
|
||
|
return $byte;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes the passed string into a signed byte on the stream.
|
||
|
*
|
||
|
* @param string $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeByte($stream)
|
||
|
{
|
||
|
$this->_stream .= pack("c",$stream);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads a signed 32-bit integer from the data stream.
|
||
|
*
|
||
|
* @return int Value is in the range of -2147483648 to 2147483647
|
||
|
*/
|
||
|
public function readInt()
|
||
|
{
|
||
|
$int = ($this->readByte() << 8) + $this->readByte();
|
||
|
return $int;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write an the integer to the output stream as a 32 bit signed integer
|
||
|
*
|
||
|
* @param int $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeInt($stream)
|
||
|
{
|
||
|
$this->_stream .= pack("n", $stream);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads a UTF-8 string from the data stream
|
||
|
*
|
||
|
* @return string A UTF-8 string produced by the byte representation of characters
|
||
|
*/
|
||
|
public function readUtf()
|
||
|
{
|
||
|
$length = $this->readInt();
|
||
|
return $this->readBytes($length);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Wite a UTF-8 string to the outputstream
|
||
|
*
|
||
|
* @param string $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeUtf($stream)
|
||
|
{
|
||
|
$this->writeInt(strlen($stream));
|
||
|
$this->_stream .= $stream;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Read a long UTF string
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function readLongUtf()
|
||
|
{
|
||
|
$length = $this->readLong();
|
||
|
return $this->readBytes($length);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write a long UTF string to the buffer
|
||
|
*
|
||
|
* @param string $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeLongUtf($stream)
|
||
|
{
|
||
|
$this->writeLong(strlen($stream));
|
||
|
$this->_stream .= $stream;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Read a long numeric value
|
||
|
*
|
||
|
* @return double
|
||
|
*/
|
||
|
public function readLong()
|
||
|
{
|
||
|
$long = ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
|
||
|
return $long;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Write long numeric value to output stream
|
||
|
*
|
||
|
* @param int|string $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeLong($stream)
|
||
|
{
|
||
|
$this->_stream .= pack("N",$stream);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Read a 16 bit unsigned short.
|
||
|
*
|
||
|
* @todo This could use the unpack() w/ S,n, or v
|
||
|
* @return double
|
||
|
*/
|
||
|
public function readUnsignedShort()
|
||
|
{
|
||
|
$byte1 = $this->readByte();
|
||
|
$byte2 = $this->readByte();
|
||
|
$short = (($byte1 << 8) | $byte2);
|
||
|
return $short;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reads an IEEE 754 double-precision floating point number from the data stream.
|
||
|
*
|
||
|
* @return double Floating point number
|
||
|
*/
|
||
|
public function readDouble()
|
||
|
{
|
||
|
$bytes = substr($this->_stream, $this->_needle, 8);
|
||
|
$this->_needle += 8;
|
||
|
$double = unpack("dflt", strrev($bytes));
|
||
|
return $double['flt'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Writes an IEEE 754 double-precision floating point number from the data stream.
|
||
|
*
|
||
|
* @param string|double $stream
|
||
|
* @return Zend_Amf_Util_BinaryStream
|
||
|
*/
|
||
|
public function writeDouble($stream)
|
||
|
{
|
||
|
$stream = pack("d", $stream);
|
||
|
if ($this->_bigEndian) {
|
||
|
$stream = strrev($stream);
|
||
|
}
|
||
|
$this->_stream .= $stream;
|
||
|
return $this;
|
||
|
}
|
||
|
}
|