web/lib/Zend/Amf/Util/BinaryStream.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Amf
       
    17  * @subpackage Util
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: BinaryStream.php 22101 2010-05-04 20:07:13Z matthew $
       
    21  */
       
    22 
       
    23 /**
       
    24  * Utility class to walk through a data stream byte by byte with conventional names
       
    25  *
       
    26  * @package    Zend_Amf
       
    27  * @subpackage Util
       
    28  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    29  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    30  */
       
    31 class Zend_Amf_Util_BinaryStream
       
    32 {
       
    33     /**
       
    34      * @var string Byte stream
       
    35      */
       
    36     protected $_stream;
       
    37 
       
    38     /**
       
    39      * @var int Length of stream
       
    40      */
       
    41     protected $_streamLength;
       
    42 
       
    43     /**
       
    44      * @var bool BigEndian encoding?
       
    45      */
       
    46     protected $_bigEndian;
       
    47 
       
    48     /**
       
    49      * @var int Current position in stream
       
    50      */
       
    51     protected $_needle;
       
    52 
       
    53     /**
       
    54      * Constructor
       
    55      *
       
    56      * Create a reference to a byte stream that is going to be parsed or created
       
    57      * by the methods in the class. Detect if the class should use big or
       
    58      * little Endian encoding.
       
    59      *
       
    60      * @param  string $stream use '' if creating a new stream or pass a string if reading.
       
    61      * @return void
       
    62      */
       
    63     public function __construct($stream)
       
    64     {
       
    65         if (!is_string($stream)) {
       
    66             require_once 'Zend/Amf/Exception.php';
       
    67             throw new Zend_Amf_Exception('Inputdata is not of type String');
       
    68         }
       
    69 
       
    70         $this->_stream       = $stream;
       
    71         $this->_needle       = 0;
       
    72         $this->_streamLength = strlen($stream);
       
    73         $this->_bigEndian    = (pack('l', 1) === "\x00\x00\x00\x01");
       
    74     }
       
    75 
       
    76     /**
       
    77      * Returns the current stream
       
    78      *
       
    79      * @return string
       
    80      */
       
    81     public function getStream()
       
    82     {
       
    83         return $this->_stream;
       
    84     }
       
    85 
       
    86     /**
       
    87      * Read the number of bytes in a row for the length supplied.
       
    88      *
       
    89      * @todo   Should check that there are enough bytes left in the stream we are about to read.
       
    90      * @param  int $length
       
    91      * @return string
       
    92      * @throws Zend_Amf_Exception for buffer underrun
       
    93      */
       
    94     public function readBytes($length)
       
    95     {
       
    96         if (($length + $this->_needle) > $this->_streamLength) {
       
    97             require_once 'Zend/Amf/Exception.php';
       
    98             throw new Zend_Amf_Exception('Buffer underrun at needle position: ' . $this->_needle . ' while requesting length: ' . $length);
       
    99         }
       
   100         $bytes = substr($this->_stream, $this->_needle, $length);
       
   101         $this->_needle+= $length;
       
   102         return $bytes;
       
   103     }
       
   104 
       
   105     /**
       
   106      * Write any length of bytes to the stream
       
   107      *
       
   108      * Usually a string.
       
   109      *
       
   110      * @param  string $bytes
       
   111      * @return Zend_Amf_Util_BinaryStream
       
   112      */
       
   113     public function writeBytes($bytes)
       
   114     {
       
   115         $this->_stream.= $bytes;
       
   116         return $this;
       
   117     }
       
   118 
       
   119     /**
       
   120      * Reads a signed byte
       
   121      *
       
   122      * @return int Value is in the range of -128 to 127.
       
   123      */
       
   124     public function readByte()
       
   125     {
       
   126         if (($this->_needle + 1) > $this->_streamLength) {
       
   127             require_once 'Zend/Amf/Exception.php';
       
   128             throw new Zend_Amf_Exception('Buffer underrun at needle position: ' . $this->_needle . ' while requesting length: ' . $length);
       
   129         }
       
   130 
       
   131         return ord($this->_stream{$this->_needle++});
       
   132     }
       
   133 
       
   134     /**
       
   135      * Writes the passed string into a signed byte on the stream.
       
   136      *
       
   137      * @param  string $stream
       
   138      * @return Zend_Amf_Util_BinaryStream
       
   139      */
       
   140     public function writeByte($stream)
       
   141     {
       
   142         $this->_stream.= pack('c', $stream);
       
   143         return $this;
       
   144     }
       
   145 
       
   146     /**
       
   147      * Reads a signed 32-bit integer from the data stream.
       
   148      *
       
   149      * @return int Value is in the range of -2147483648 to 2147483647
       
   150      */
       
   151     public function readInt()
       
   152     {
       
   153         return ($this->readByte() << 8) + $this->readByte();
       
   154     }
       
   155 
       
   156     /**
       
   157      * Write an the integer to the output stream as a 32 bit signed integer
       
   158      *
       
   159      * @param  int $stream
       
   160      * @return Zend_Amf_Util_BinaryStream
       
   161      */
       
   162     public function writeInt($stream)
       
   163     {
       
   164         $this->_stream.= pack('n', $stream);
       
   165         return $this;
       
   166     }
       
   167 
       
   168     /**
       
   169      * Reads a UTF-8 string from the data stream
       
   170      *
       
   171      * @return string A UTF-8 string produced by the byte representation of characters
       
   172      */
       
   173     public function readUtf()
       
   174     {
       
   175         $length = $this->readInt();
       
   176         return $this->readBytes($length);
       
   177     }
       
   178 
       
   179     /**
       
   180      * Wite a UTF-8 string to the outputstream
       
   181      *
       
   182      * @param  string $stream
       
   183      * @return Zend_Amf_Util_BinaryStream
       
   184      */
       
   185     public function writeUtf($stream)
       
   186     {
       
   187         $this->writeInt(strlen($stream));
       
   188         $this->_stream.= $stream;
       
   189         return $this;
       
   190     }
       
   191 
       
   192 
       
   193     /**
       
   194      * Read a long UTF string
       
   195      *
       
   196      * @return string
       
   197      */
       
   198     public function readLongUtf()
       
   199     {
       
   200         $length = $this->readLong();
       
   201         return $this->readBytes($length);
       
   202     }
       
   203 
       
   204     /**
       
   205      * Write a long UTF string to the buffer
       
   206      *
       
   207      * @param  string $stream
       
   208      * @return Zend_Amf_Util_BinaryStream
       
   209      */
       
   210     public function writeLongUtf($stream)
       
   211     {
       
   212         $this->writeLong(strlen($stream));
       
   213         $this->_stream.= $stream;
       
   214     }
       
   215 
       
   216     /**
       
   217      * Read a long numeric value
       
   218      *
       
   219      * @return double
       
   220      */
       
   221     public function readLong()
       
   222     {
       
   223         return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
       
   224     }
       
   225 
       
   226     /**
       
   227      * Write long numeric value to output stream
       
   228      *
       
   229      * @param  int|string $stream
       
   230      * @return Zend_Amf_Util_BinaryStream
       
   231      */
       
   232     public function writeLong($stream)
       
   233     {
       
   234         $this->_stream.= pack('N', $stream);
       
   235         return $this;
       
   236     }
       
   237 
       
   238     /**
       
   239      * Read a 16 bit unsigned short.
       
   240      *
       
   241      * @todo   This could use the unpack() w/ S,n, or v
       
   242      * @return double
       
   243      */
       
   244     public function readUnsignedShort()
       
   245     {
       
   246         $byte1 = $this->readByte();
       
   247         $byte2 = $this->readByte();
       
   248         return (($byte1 << 8) | $byte2);
       
   249     }
       
   250 
       
   251     /**
       
   252      * Reads an IEEE 754 double-precision floating point number from the data stream.
       
   253      *
       
   254      * @return double Floating point number
       
   255      */
       
   256     public function readDouble()
       
   257     {
       
   258         $bytes = substr($this->_stream, $this->_needle, 8);
       
   259         $this->_needle+= 8;
       
   260 
       
   261         if (!$this->_bigEndian) {
       
   262             $bytes = strrev($bytes);
       
   263         }
       
   264 
       
   265         $double = unpack('dflt', $bytes);
       
   266         return $double['flt'];
       
   267     }
       
   268 
       
   269     /**
       
   270      * Writes an IEEE 754 double-precision floating point number from the data stream.
       
   271      *
       
   272      * @param  string|double $stream
       
   273      * @return Zend_Amf_Util_BinaryStream
       
   274      */
       
   275     public function writeDouble($stream)
       
   276     {
       
   277         $stream = pack('d', $stream);
       
   278         if (!$this->_bigEndian) {
       
   279             $stream = strrev($stream);
       
   280         }
       
   281         $this->_stream.= $stream;
       
   282         return $this;
       
   283     }
       
   284 
       
   285 }