[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Amf 17 * @subpackage Parse_Amf3 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$ 21 */ 22 23 /** Zend_Amf_Parse_Deserializer */ 24 require_once 'Zend/Amf/Parse/Deserializer.php'; 25 26 /** Zend_Amf_Parse_TypeLoader */ 27 require_once 'Zend/Amf/Parse/TypeLoader.php'; 28 29 /** 30 * Read an AMF3 input stream and convert it into PHP data types. 31 * 32 * @todo readObject to handle Typed Objects 33 * @todo readXMLStrimg to be implemented. 34 * @todo Class could be implemented as Factory Class with each data type it's own class. 35 * @package Zend_Amf 36 * @subpackage Parse_Amf3 37 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 38 * @license http://framework.zend.com/license/new-bsd New BSD License 39 */ 40 class Zend_Amf_Parse_Amf3_Deserializer extends Zend_Amf_Parse_Deserializer 41 { 42 /** 43 * Total number of objects in the referenceObject array 44 * @var int 45 */ 46 protected $_objectCount; 47 48 /** 49 * An array of reference objects per amf body 50 * @var array 51 */ 52 protected $_referenceObjects = array(); 53 54 /** 55 * An array of reference strings per amf body 56 * @var array 57 */ 58 protected $_referenceStrings = array(); 59 60 /** 61 * An array of reference class definitions per body 62 * @var array 63 */ 64 protected $_referenceDefinitions = array(); 65 66 /** 67 * Read AMF markers and dispatch for deserialization 68 * 69 * Checks for AMF marker types and calls the appropriate methods 70 * for deserializing those marker types. markers are the data type of 71 * the following value. 72 * 73 * @param integer $typeMarker 74 * @return mixed Whatever the corresponding PHP data type is 75 * @throws Zend_Amf_Exception for unidentified marker type 76 */ 77 public function readTypeMarker($typeMarker = null) 78 { 79 if(null === $typeMarker) { 80 $typeMarker = $this->_stream->readByte(); 81 } 82 83 switch($typeMarker) { 84 case Zend_Amf_Constants::AMF3_UNDEFINED: 85 return null; 86 case Zend_Amf_Constants::AMF3_NULL: 87 return null; 88 case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE: 89 return false; 90 case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE: 91 return true; 92 case Zend_Amf_Constants::AMF3_INTEGER: 93 return $this->readInteger(); 94 case Zend_Amf_Constants::AMF3_NUMBER: 95 return $this->_stream->readDouble(); 96 case Zend_Amf_Constants::AMF3_STRING: 97 return $this->readString(); 98 case Zend_Amf_Constants::AMF3_DATE: 99 return $this->readDate(); 100 case Zend_Amf_Constants::AMF3_ARRAY: 101 return $this->readArray(); 102 case Zend_Amf_Constants::AMF3_OBJECT: 103 return $this->readObject(); 104 case Zend_Amf_Constants::AMF3_XML: 105 case Zend_Amf_Constants::AMF3_XMLSTRING: 106 return $this->readXmlString(); 107 case Zend_Amf_Constants::AMF3_BYTEARRAY: 108 return $this->readString(); 109 default: 110 require_once 'Zend/Amf/Exception.php'; 111 throw new Zend_Amf_Exception('Unsupported type marker: ' . $typeMarker); 112 } 113 } 114 115 /** 116 * Read and deserialize an integer 117 * 118 * AMF 3 represents smaller integers with fewer bytes using the most 119 * significant bit of each byte. The worst case uses 32-bits 120 * to represent a 29-bit number, which is what we would have 121 * done with no compression. 122 * - 0x00000000 - 0x0000007F : 0xxxxxxx 123 * - 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx 124 * - 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx 125 * - 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx 126 * - 0x40000000 - 0xFFFFFFFF : throw range exception 127 * 128 * 0x04 -> integer type code, followed by up to 4 bytes of data. 129 * 130 * Parsing integers on OSFlash for the AMF3 integer data format: 131 * @link http://osflash.org/amf3/parsing_integers 132 * @return int|float 133 */ 134 public function readInteger() 135 { 136 $count = 1; 137 $intReference = $this->_stream->readByte(); 138 $result = 0; 139 while ((($intReference & 0x80) != 0) && $count < 4) { 140 $result <<= 7; 141 $result |= ($intReference & 0x7f); 142 $intReference = $this->_stream->readByte(); 143 $count++; 144 } 145 if ($count < 4) { 146 $result <<= 7; 147 $result |= $intReference; 148 } else { 149 // Use all 8 bits from the 4th byte 150 $result <<= 8; 151 $result |= $intReference; 152 153 // Check if the integer should be negative 154 if (($result & 0x10000000) != 0) { 155 //and extend the sign bit 156 $result |= ~0xFFFFFFF; 157 } 158 } 159 return $result; 160 } 161 162 /** 163 * Read and deserialize a string 164 * 165 * Strings can be sent as a reference to a previously 166 * occurring String by using an index to the implicit string reference table. 167 * Strings are encoding using UTF-8 - however the header may either 168 * describe a string literal or a string reference. 169 * 170 * - string = 0x06 string-data 171 * - string-data = integer-data [ modified-utf-8 ] 172 * - modified-utf-8 = *OCTET 173 * 174 * @return String 175 */ 176 public function readString() 177 { 178 $stringReference = $this->readInteger(); 179 180 //Check if this is a reference string 181 if (($stringReference & 0x01) == 0) { 182 // reference string 183 $stringReference = $stringReference >> 1; 184 if ($stringReference >= count($this->_referenceStrings)) { 185 require_once 'Zend/Amf/Exception.php'; 186 throw new Zend_Amf_Exception('Undefined string reference: ' . $stringReference); 187 } 188 // reference string found 189 return $this->_referenceStrings[$stringReference]; 190 } 191 192 $length = $stringReference >> 1; 193 if ($length) { 194 $string = $this->_stream->readBytes($length); 195 $this->_referenceStrings[] = $string; 196 } else { 197 $string = ""; 198 } 199 return $string; 200 } 201 202 /** 203 * Read and deserialize a date 204 * 205 * Data is the number of milliseconds elapsed since the epoch 206 * of midnight, 1st Jan 1970 in the UTC time zone. 207 * Local time zone information is not sent to flash. 208 * 209 * - date = 0x08 integer-data [ number-data ] 210 * 211 * @return Zend_Date 212 */ 213 public function readDate() 214 { 215 $dateReference = $this->readInteger(); 216 if (($dateReference & 0x01) == 0) { 217 $dateReference = $dateReference >> 1; 218 if ($dateReference>=count($this->_referenceObjects)) { 219 require_once 'Zend/Amf/Exception.php'; 220 throw new Zend_Amf_Exception('Undefined date reference: ' . $dateReference); 221 } 222 return $this->_referenceObjects[$dateReference]; 223 } 224 225 $timestamp = floor($this->_stream->readDouble() / 1000); 226 227 require_once 'Zend/Date.php'; 228 $dateTime = new Zend_Date((int) $timestamp); 229 $this->_referenceObjects[] = $dateTime; 230 return $dateTime; 231 } 232 233 /** 234 * Read amf array to PHP array 235 * 236 * - array = 0x09 integer-data ( [ 1OCTET *amf3-data ] | [OCTET *amf3-data 1] | [ OCTET *amf-data ] ) 237 * 238 * @return array 239 */ 240 public function readArray() 241 { 242 $arrayReference = $this->readInteger(); 243 if (($arrayReference & 0x01)==0){ 244 $arrayReference = $arrayReference >> 1; 245 if ($arrayReference>=count($this->_referenceObjects)) { 246 require_once 'Zend/Amf/Exception.php'; 247 throw new Zend_Amf_Exception('Unknow array reference: ' . $arrayReference); 248 } 249 return $this->_referenceObjects[$arrayReference]; 250 } 251 252 // Create a holder for the array in the reference list 253 $data = array(); 254 $this->_referenceObjects[] =& $data; 255 $key = $this->readString(); 256 257 // Iterating for string based keys. 258 while ($key != '') { 259 $data[$key] = $this->readTypeMarker(); 260 $key = $this->readString(); 261 } 262 263 $arrayReference = $arrayReference >>1; 264 265 //We have a dense array 266 for ($i=0; $i < $arrayReference; $i++) { 267 $data[] = $this->readTypeMarker(); 268 } 269 270 return $data; 271 } 272 273 /** 274 * Read an object from the AMF stream and convert it into a PHP object 275 * 276 * @todo Rather than using an array of traitsInfo create Zend_Amf_Value_TraitsInfo 277 * @return object|array 278 */ 279 public function readObject() 280 { 281 $traitsInfo = $this->readInteger(); 282 $storedObject = ($traitsInfo & 0x01)==0; 283 $traitsInfo = $traitsInfo >> 1; 284 285 // Check if the Object is in the stored Objects reference table 286 if ($storedObject) { 287 $ref = $traitsInfo; 288 if (!isset($this->_referenceObjects[$ref])) { 289 require_once 'Zend/Amf/Exception.php'; 290 throw new Zend_Amf_Exception('Unknown Object reference: ' . $ref); 291 } 292 $returnObject = $this->_referenceObjects[$ref]; 293 } else { 294 // Check if the Object is in the stored Definitions reference table 295 $storedClass = ($traitsInfo & 0x01) == 0; 296 $traitsInfo = $traitsInfo >> 1; 297 if ($storedClass) { 298 $ref = $traitsInfo; 299 if (!isset($this->_referenceDefinitions[$ref])) { 300 require_once 'Zend/Amf/Exception.php'; 301 throw new Zend_Amf_Exception('Unknows Definition reference: '. $ref); 302 } 303 // Populate the reference attributes 304 $className = $this->_referenceDefinitions[$ref]['className']; 305 $encoding = $this->_referenceDefinitions[$ref]['encoding']; 306 $propertyNames = $this->_referenceDefinitions[$ref]['propertyNames']; 307 } else { 308 // The class was not in the reference tables. Start reading rawdata to build traits. 309 // Create a traits table. Zend_Amf_Value_TraitsInfo would be ideal 310 $className = $this->readString(); 311 $encoding = $traitsInfo & 0x03; 312 $propertyNames = array(); 313 $traitsInfo = $traitsInfo >> 2; 314 } 315 316 // We now have the object traits defined in variables. Time to go to work: 317 if (!$className) { 318 // No class name generic object 319 $returnObject = new stdClass(); 320 } else { 321 // Defined object 322 // Typed object lookup against registered classname maps 323 if ($loader = Zend_Amf_Parse_TypeLoader::loadType($className)) { 324 $returnObject = new $loader(); 325 } else { 326 //user defined typed object 327 require_once 'Zend/Amf/Exception.php'; 328 throw new Zend_Amf_Exception('Typed object not found: '. $className . ' '); 329 } 330 } 331 332 // Add the Object to the reference table 333 $this->_referenceObjects[] = $returnObject; 334 335 $properties = array(); // clear value 336 // Check encoding types for additional processing. 337 switch ($encoding) { 338 case (Zend_Amf_Constants::ET_EXTERNAL): 339 // Externalizable object such as {ArrayCollection} and {ObjectProxy} 340 if (!$storedClass) { 341 $this->_referenceDefinitions[] = array( 342 'className' => $className, 343 'encoding' => $encoding, 344 'propertyNames' => $propertyNames, 345 ); 346 } 347 $returnObject->externalizedData = $this->readTypeMarker(); 348 break; 349 case (Zend_Amf_Constants::ET_DYNAMIC): 350 // used for Name-value encoding 351 if (!$storedClass) { 352 $this->_referenceDefinitions[] = array( 353 'className' => $className, 354 'encoding' => $encoding, 355 'propertyNames' => $propertyNames, 356 ); 357 } 358 // not a reference object read name value properties from byte stream 359 do { 360 $property = $this->readString(); 361 if ($property != "") { 362 $propertyNames[] = $property; 363 $properties[$property] = $this->readTypeMarker(); 364 } 365 } while ($property !=""); 366 break; 367 default: 368 // basic property list object. 369 if (!$storedClass) { 370 $count = $traitsInfo; // Number of properties in the list 371 for($i=0; $i< $count; $i++) { 372 $propertyNames[] = $this->readString(); 373 } 374 // Add a reference to the class. 375 $this->_referenceDefinitions[] = array( 376 'className' => $className, 377 'encoding' => $encoding, 378 'propertyNames' => $propertyNames, 379 ); 380 } 381 foreach ($propertyNames as $property) { 382 $properties[$property] = $this->readTypeMarker(); 383 } 384 break; 385 } 386 387 // Add properties back to the return object. 388 foreach($properties as $key=>$value) { 389 if($key) { 390 $returnObject->$key = $value; 391 } 392 } 393 394 395 } 396 397 if ($returnObject instanceof Zend_Amf_Value_Messaging_ArrayCollection) { 398 if (isset($returnObject->externalizedData)) { 399 $returnObject = $returnObject->externalizedData; 400 } else { 401 $returnObject = get_object_vars($returnObject); 402 } 403 } 404 405 return $returnObject; 406 } 407 408 /** 409 * Convert XML to SimpleXml 410 * If user wants DomDocument they can use dom_import_simplexml 411 * 412 * @return SimpleXml Object 413 */ 414 public function readXmlString() 415 { 416 $xmlReference = $this->readInteger(); 417 $length = $xmlReference >> 1; 418 $string = $this->_stream->readBytes($length); 419 return simplexml_load_string($string); 420 } 421 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |