File indexing completed on 2024-12-22 05:36:27
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Amf 0017 * @subpackage Util 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * Utility class to walk through a data stream byte by byte with conventional names 0025 * 0026 * @package Zend_Amf 0027 * @subpackage Util 0028 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0029 * @license http://framework.zend.com/license/new-bsd New BSD License 0030 */ 0031 class Zend_Amf_Util_BinaryStream 0032 { 0033 /** 0034 * @var string Byte stream 0035 */ 0036 protected $_stream; 0037 0038 /** 0039 * @var int Length of stream 0040 */ 0041 protected $_streamLength; 0042 0043 /** 0044 * @var bool BigEndian encoding? 0045 */ 0046 protected $_bigEndian; 0047 0048 /** 0049 * @var int Current position in stream 0050 */ 0051 protected $_needle; 0052 0053 /** 0054 * @var bool str* functions overloaded using mbstring.func_overload? 0055 */ 0056 protected $_mbStringFunctionsOverloaded; 0057 0058 /** 0059 * Constructor 0060 * 0061 * Create a reference to a byte stream that is going to be parsed or created 0062 * by the methods in the class. Detect if the class should use big or 0063 * little Endian encoding. 0064 * 0065 * @param string $stream use '' if creating a new stream or pass a string if reading. 0066 * @return void 0067 */ 0068 public function __construct($stream) 0069 { 0070 if (!is_string($stream)) { 0071 // require_once 'Zend/Amf/Exception.php'; 0072 throw new Zend_Amf_Exception('Inputdata is not of type String'); 0073 } 0074 0075 $this->_stream = $stream; 0076 $this->_needle = 0; 0077 $this->_mbStringFunctionsOverloaded = function_exists('mb_strlen') && (ini_get('mbstring.func_overload') !== '') && ((int)ini_get('mbstring.func_overload') & 2); 0078 $this->_streamLength = $this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream); 0079 $this->_bigEndian = (pack('l', 1) === "\x00\x00\x00\x01"); 0080 } 0081 0082 /** 0083 * Returns the current stream 0084 * 0085 * @return string 0086 */ 0087 public function getStream() 0088 { 0089 return $this->_stream; 0090 } 0091 0092 /** 0093 * Read the number of bytes in a row for the length supplied. 0094 * 0095 * @todo Should check that there are enough bytes left in the stream we are about to read. 0096 * @param int $length 0097 * @return string 0098 * @throws Zend_Amf_Exception for buffer underrun 0099 */ 0100 public function readBytes($length) 0101 { 0102 if (($length + $this->_needle) > $this->_streamLength) { 0103 // require_once 'Zend/Amf/Exception.php'; 0104 throw new Zend_Amf_Exception('Buffer underrun at needle position: ' . $this->_needle . ' while requesting length: ' . $length); 0105 } 0106 $bytes = $this->_mbStringFunctionsOverloaded ? mb_substr($this->_stream, $this->_needle, $length, '8bit') : substr($this->_stream, $this->_needle, $length); 0107 $this->_needle+= $length; 0108 return $bytes; 0109 } 0110 0111 /** 0112 * Write any length of bytes to the stream 0113 * 0114 * Usually a string. 0115 * 0116 * @param string $bytes 0117 * @return Zend_Amf_Util_BinaryStream 0118 */ 0119 public function writeBytes($bytes) 0120 { 0121 $this->_stream.= $bytes; 0122 return $this; 0123 } 0124 0125 /** 0126 * Reads a signed byte 0127 * 0128 * @return int Value is in the range of -128 to 127. 0129 * @throws Zend_Amf_Exception 0130 */ 0131 public function readByte() 0132 { 0133 if (($this->_needle + 1) > $this->_streamLength) { 0134 // require_once 'Zend/Amf/Exception.php'; 0135 throw new Zend_Amf_Exception( 0136 'Buffer underrun at needle position: ' 0137 . $this->_needle 0138 . ' while requesting length: ' 0139 . $this->_streamLength 0140 ); 0141 } 0142 0143 return ord($this->_stream{$this->_needle++}); 0144 } 0145 0146 /** 0147 * Writes the passed string into a signed byte on the stream. 0148 * 0149 * @param string $stream 0150 * @return Zend_Amf_Util_BinaryStream 0151 */ 0152 public function writeByte($stream) 0153 { 0154 $this->_stream.= pack('c', $stream); 0155 return $this; 0156 } 0157 0158 /** 0159 * Reads a signed 32-bit integer from the data stream. 0160 * 0161 * @return int Value is in the range of -2147483648 to 2147483647 0162 */ 0163 public function readInt() 0164 { 0165 return ($this->readByte() << 8) + $this->readByte(); 0166 } 0167 0168 /** 0169 * Write an the integer to the output stream as a 32 bit signed integer 0170 * 0171 * @param int $stream 0172 * @return Zend_Amf_Util_BinaryStream 0173 */ 0174 public function writeInt($stream) 0175 { 0176 $this->_stream.= pack('n', $stream); 0177 return $this; 0178 } 0179 0180 /** 0181 * Reads a UTF-8 string from the data stream 0182 * 0183 * @return string A UTF-8 string produced by the byte representation of characters 0184 */ 0185 public function readUtf() 0186 { 0187 $length = $this->readInt(); 0188 return $this->readBytes($length); 0189 } 0190 0191 /** 0192 * Wite a UTF-8 string to the outputstream 0193 * 0194 * @param string $stream 0195 * @return Zend_Amf_Util_BinaryStream 0196 */ 0197 public function writeUtf($stream) 0198 { 0199 $this->writeInt($this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream)); 0200 $this->_stream.= $stream; 0201 return $this; 0202 } 0203 0204 0205 /** 0206 * Read a long UTF string 0207 * 0208 * @return string 0209 */ 0210 public function readLongUtf() 0211 { 0212 $length = $this->readLong(); 0213 return $this->readBytes($length); 0214 } 0215 0216 /** 0217 * Write a long UTF string to the buffer 0218 * 0219 * @param string $stream 0220 * @return Zend_Amf_Util_BinaryStream 0221 */ 0222 public function writeLongUtf($stream) 0223 { 0224 $this->writeLong($this->_mbStringFunctionsOverloaded ? mb_strlen($stream, '8bit') : strlen($stream)); 0225 $this->_stream.= $stream; 0226 } 0227 0228 /** 0229 * Read a long numeric value 0230 * 0231 * @return double 0232 */ 0233 public function readLong() 0234 { 0235 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte(); 0236 } 0237 0238 /** 0239 * Write long numeric value to output stream 0240 * 0241 * @param int|string $stream 0242 * @return Zend_Amf_Util_BinaryStream 0243 */ 0244 public function writeLong($stream) 0245 { 0246 $this->_stream.= pack('N', $stream); 0247 return $this; 0248 } 0249 0250 /** 0251 * Read a 16 bit unsigned short. 0252 * 0253 * @todo This could use the unpack() w/ S,n, or v 0254 * @return double 0255 */ 0256 public function readUnsignedShort() 0257 { 0258 $byte1 = $this->readByte(); 0259 $byte2 = $this->readByte(); 0260 return (($byte1 << 8) | $byte2); 0261 } 0262 0263 /** 0264 * Reads an IEEE 754 double-precision floating point number from the data stream. 0265 * 0266 * @return double Floating point number 0267 */ 0268 public function readDouble() 0269 { 0270 $bytes = $this->_mbStringFunctionsOverloaded ? mb_substr($this->_stream, $this->_needle, 8, '8bit') : substr($this->_stream, $this->_needle, 8); 0271 $this->_needle+= 8; 0272 0273 if (!$this->_bigEndian) { 0274 $bytes = strrev($bytes); 0275 } 0276 0277 $double = unpack('dflt', $bytes); 0278 return $double['flt']; 0279 } 0280 0281 /** 0282 * Writes an IEEE 754 double-precision floating point number from the data stream. 0283 * 0284 * @param string|double $stream 0285 * @return Zend_Amf_Util_BinaryStream 0286 */ 0287 public function writeDouble($stream) 0288 { 0289 $stream = pack('d', $stream); 0290 if (!$this->_bigEndian) { 0291 $stream = strrev($stream); 0292 } 0293 $this->_stream.= $stream; 0294 return $this; 0295 } 0296 0297 }