PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/application/library/Zend/Amf/Parse/Amf3/Serializer.php

https://github.com/iulianmanole/dcms
PHP | 342 lines | 225 code | 27 blank | 90 comment | 36 complexity | 65a1c7e4fa1d8c8fce9e72884eae9f50 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0, MIT
  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 Parse_Amf3
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /** Zend_Amf_Parse_Serializer */
  22. require_once 'Zend/Amf/Parse/Serializer.php';
  23. /** Zend_Amf_Parse_TypeLoader */
  24. require_once 'Zend/Amf/Parse/TypeLoader.php';
  25. /**
  26. * Detect PHP object type and convert it to a corresponding AMF3 object type
  27. *
  28. * @package Zend_Amf
  29. * @subpackage Parse_Amf3
  30. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Amf_Parse_Amf3_Serializer extends Zend_Amf_Parse_Serializer
  34. {
  35. /**
  36. * Serialize PHP types to AMF3 and write to stream
  37. *
  38. * Checks to see if the type was declared and then either
  39. * auto negotiates the type or use the user defined markerType to
  40. * serialize the data from php back to AMF3
  41. *
  42. * @param mixed $content
  43. * @param int $markerType
  44. * @return void
  45. */
  46. public function writeTypeMarker($data, $markerType=null)
  47. {
  48. if (null !== $markerType) {
  49. // Write the Type Marker to denote the following action script data type
  50. $this->_stream->writeByte($markerType);
  51. switch ($markerType) {
  52. case Zend_Amf_Constants::AMF3_NULL:
  53. break;
  54. case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE:
  55. break;
  56. case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE:
  57. break;
  58. case Zend_Amf_Constants::AMF3_INTEGER:
  59. $this->writeInteger($data);
  60. break;
  61. case Zend_Amf_Constants::AMF3_NUMBER:
  62. $this->_stream->writeDouble($data);
  63. break;
  64. case Zend_Amf_Constants::AMF3_STRING:
  65. $this->writeString($data);
  66. break;
  67. case Zend_Amf_Constants::AMF3_DATE:
  68. $this->writeDate($data);
  69. break;
  70. case Zend_Amf_Constants::AMF3_ARRAY:
  71. $this->writeArray($data);
  72. break;
  73. case Zend_Amf_Constants::AMF3_OBJECT:
  74. $this->writeObject($data);
  75. break;
  76. case Zend_Amf_Constants::AMF3_BYTEARRAY:
  77. $this->writeString($data instanceof Zend_Amf_Value_ByteArray ? $data->getData() : $data);
  78. break;
  79. case Zend_Amf_Constants::AMF3_XMLSTRING;
  80. $this->writeString($data);
  81. break;
  82. default:
  83. require_once 'Zend/Amf/Exception.php';
  84. throw new Zend_Amf_Exception('Unknown Type Marker: ' . $markerType);
  85. }
  86. } else {
  87. // Detect Type Marker
  88. if(is_resource($data)) {
  89. $data = Zend_Amf_Parse_TypeLoader::handleResource($data);
  90. }
  91. switch (true) {
  92. case (null === $data):
  93. $markerType = Zend_Amf_Constants::AMF3_NULL;
  94. break;
  95. case (is_bool($data)):
  96. if ($data){
  97. $markerType = Zend_Amf_Constants::AMF3_BOOLEAN_TRUE;
  98. } else {
  99. $markerType = Zend_Amf_Constants::AMF3_BOOLEAN_FALSE;
  100. }
  101. break;
  102. case (is_int($data)):
  103. if (($data > 0xFFFFFFF) || ($data < -268435456)) {
  104. $markerType = Zend_Amf_Constants::AMF3_NUMBER;
  105. } else {
  106. $markerType = Zend_Amf_Constants::AMF3_INTEGER;
  107. }
  108. break;
  109. case (is_float($data)):
  110. $markerType = Zend_Amf_Constants::AMF3_NUMBER;
  111. break;
  112. case (is_string($data)):
  113. $markerType = Zend_Amf_Constants::AMF3_STRING;
  114. break;
  115. case (is_array($data)):
  116. $markerType = Zend_Amf_Constants::AMF3_ARRAY;
  117. break;
  118. case (is_object($data)):
  119. // Handle object types.
  120. if (($data instanceof DateTime) || ($data instanceof Zend_Date)) {
  121. $markerType = Zend_Amf_Constants::AMF3_DATE;
  122. } else if ($data instanceof Zend_Amf_Value_ByteArray) {
  123. $markerType = Zend_Amf_Constants::AMF3_BYTEARRAY;
  124. } else if ($data instanceof DOMDocument) {
  125. // convert object to string
  126. $data = $data->saveXml();
  127. $markerType = Zend_Amf_Constants::AMF3_XMLSTRING;
  128. } else if ($data instanceof SimpleXMLElement) {
  129. // convert object to string;
  130. $data = $data->asXML();
  131. $markerType = Zend_Amf_Constants::AMF3_XMLSTRING;
  132. } else {
  133. $markerType = Zend_Amf_Constants::AMF3_OBJECT;
  134. }
  135. break;
  136. default:
  137. require_once 'Zend/Amf/Exception.php';
  138. throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data));
  139. }
  140. $this->writeTypeMarker($data, $markerType);
  141. }
  142. }
  143. /**
  144. * Write an AMF3 integer
  145. *
  146. * @param int|float $data
  147. * @return Zend_Amf_Parse_Amf3_Serializer
  148. */
  149. public function writeInteger($int)
  150. {
  151. if (($int & 0xffffff80) == 0) {
  152. $this->_stream->writeByte($int & 0x7f);
  153. return $this;
  154. }
  155. if (($int & 0xffffc000) == 0 ) {
  156. $this->_stream->writeByte(($int >> 7 ) | 0x80);
  157. $this->_stream->writeByte($int & 0x7f);
  158. return $this;
  159. }
  160. if (($int & 0xffe00000) == 0) {
  161. $this->_stream->writeByte(($int >> 14 ) | 0x80);
  162. $this->_stream->writeByte(($int >> 7 ) | 0x80);
  163. $this->_stream->writeByte($int & 0x7f);
  164. return $this;
  165. }
  166. $this->_stream->writeByte(($int >> 22 ) | 0x80);
  167. $this->_stream->writeByte(($int >> 15 ) | 0x80);
  168. $this->_stream->writeByte(($int >> 8 ) | 0x80);
  169. $this->_stream->writeByte($int & 0xff);
  170. return $this;
  171. }
  172. /**
  173. * Send string to output stream
  174. *
  175. * @param string $string
  176. * @return Zend_Amf_Parse_Amf3_Serializer
  177. */
  178. public function writeString($string)
  179. {
  180. $ref = strlen($string) << 1 | 0x01;
  181. $this->writeInteger($ref);
  182. $this->_stream->writeBytes($string);
  183. return $this;
  184. }
  185. /**
  186. * Convert DateTime/Zend_Date to AMF date
  187. *
  188. * @param DateTime|Zend_Date $date
  189. * @return Zend_Amf_Parse_Amf3_Serializer
  190. */
  191. public function writeDate($date)
  192. {
  193. if ($date instanceof DateTime) {
  194. $dateString = $date->format('U') * 1000;
  195. } elseif ($date instanceof Zend_Date) {
  196. $dateString = $date->toString('U') * 1000;
  197. } else {
  198. require_once 'Zend/Amf/Exception.php';
  199. throw new Zend_Amf_Exception('Invalid date specified; must be a string DateTime or Zend_Date object');
  200. }
  201. $this->writeInteger(0x01);
  202. // write time to stream minus milliseconds
  203. $this->_stream->writeDouble($dateString);
  204. return $this;
  205. }
  206. /**
  207. * Write a PHP array back to the amf output stream
  208. *
  209. * @param array $array
  210. * @return Zend_Amf_Parse_Amf3_Serializer
  211. */
  212. public function writeArray(array $array)
  213. {
  214. // have to seperate mixed from numberic keys.
  215. $numeric = array();
  216. $string = array();
  217. foreach ($array as $key => $value) {
  218. if (is_int($key)) {
  219. $numeric[] = $value;
  220. } else {
  221. $string[$key] = $value;
  222. }
  223. }
  224. // write the preamble id of the array
  225. $length = count($numeric);
  226. $id = ($length << 1) | 0x01;
  227. $this->writeInteger($id);
  228. //Write the mixed type array to the output stream
  229. foreach($string as $key => $value) {
  230. $this->writeString($key)
  231. ->writeTypeMarker($value);
  232. }
  233. $this->writeString('');
  234. // Write the numeric array to ouput stream
  235. foreach($numeric as $value) {
  236. $this->writeTypeMarker($value);
  237. }
  238. return $this;
  239. }
  240. /**
  241. * Write object to ouput stream
  242. *
  243. * @param mixed $data
  244. * @return Zend_Amf_Parse_Amf3_Serializer
  245. */
  246. public function writeObject($object)
  247. {
  248. $encoding = Zend_Amf_Constants::ET_PROPLIST;
  249. $className = '';
  250. //Check to see if the object is a typed object and we need to change
  251. switch (true) {
  252. // the return class mapped name back to actionscript class name.
  253. case ($className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object))):
  254. break;
  255. // Check to see if the user has defined an explicit Action Script type.
  256. case isset($object->_explicitType):
  257. $className = $object->_explicitType;
  258. break;
  259. // Check if user has defined a method for accessing the Action Script type
  260. case method_exists($object, 'getASClassName'):
  261. $className = $object->getASClassName();
  262. break;
  263. // No return class name is set make it a generic object
  264. case ($object instanceof stdClass):
  265. $className = '';
  266. break;
  267. // By default, use object's class name
  268. default:
  269. $className = get_class($object);
  270. break;
  271. }
  272. $traitsInfo = Zend_Amf_Constants::AMF3_OBJECT_ENCODING;
  273. $traitsInfo |= $encoding << 2;
  274. try {
  275. switch($encoding) {
  276. case Zend_Amf_Constants::ET_PROPLIST:
  277. $count = 0;
  278. foreach($object as $key => $value) {
  279. if( $key[0] != "_") {
  280. $count++;
  281. }
  282. }
  283. $traitsInfo |= ($count << 4);
  284. // Write the object ID
  285. $this->writeInteger($traitsInfo);
  286. // Write the classname
  287. $this->writeString($className);
  288. // Write the object Key's to the output stream
  289. foreach ($object as $key => $value) {
  290. if( $key[0] != "_") {
  291. $this->writeString($key);
  292. }
  293. }
  294. //Write the object values to the output stream.
  295. foreach ($object as $key => $value) {
  296. if( $key[0] != "_") {
  297. $this->writeTypeMarker($value);
  298. }
  299. }
  300. break;
  301. case Zend_Amf_Constants::ET_EXTERNAL:
  302. require_once 'Zend/Amf/Exception.php';
  303. throw new Zend_Amf_Exception('External Object Encoding not implemented');
  304. break;
  305. default:
  306. require_once 'Zend/Amf/Exception.php';
  307. throw new Zend_Amf_Exception('Unknown Object Encoding type: ' . $encoding);
  308. }
  309. } catch (Exception $e) {
  310. require_once 'Zend/Amf/Exception.php';
  311. throw new Zend_Amf_Exception('Unable to writeObject output: ' . $e->getMessage());
  312. }
  313. return $this;
  314. }
  315. }