PageRenderTime 129ms CodeModel.GetById 61ms app.highlight 6ms RepoModel.GetById 54ms app.codeStats 5ms

/Amf/Util/BinaryStream.php

https://bitbucket.org/gkawka/zend-framework
PHP | 285 lines | 115 code | 27 blank | 143 comment | 5 complexity | e72042d02676e1de5c1580332c0e74e1 MD5 | raw file
  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-2012 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 24593 2012-01-05 20:35:02Z 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-2012 Zend Technologies USA Inc. (http://www.zend.com)
 29 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 30 */
 31class 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}