PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/amfphp/core/amf/io/AMFBaseSerializer.php

https://gitlab.com/endomorphosis/suschu
PHP | 327 lines | 217 code | 30 blank | 80 comment | 45 complexity | 066e9eaaa4696e2830708c5daa67a17a MD5 | raw file
  1. <?php
  2. /**
  3. * AMFSerializer manages the job of translating PHP objects into
  4. * the actionscript equivalent via amf. The main method of the serializer
  5. * is the serialize method which takes and AMFObject as it's argument
  6. * and builds the resulting amf body.
  7. *
  8. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  9. * @copyright (c) 2003 amfphp.org
  10. * @package flashservices
  11. * @subpackage io
  12. * @version $Id: AMFSerializer.php,v 1.39 2005/07/22 10:58:11 pmineault Exp $
  13. */
  14. class AMFBaseSerializer {
  15. /**
  16. * Classes that are serialized as recordsets
  17. */
  18. var $amf0StoredObjects = array();
  19. var $storedObjects = array();
  20. var $storedDefinitions = 0;
  21. var $storedStrings = array();
  22. var $outBuffer;
  23. var $encounteredStrings = 0;
  24. var $native = false;
  25. /**
  26. * AMFSerializer is the constructor function. You must pass the
  27. * method an AMFOutputStream as the single argument.
  28. *
  29. * @param object $stream The AMFOutputStream
  30. */
  31. function AMFBaseSerializer() {
  32. $this->isBigEndian = AMFPHP_BIG_ENDIAN;
  33. $this->outBuffer = ""; // the buffer
  34. $this->charsetHandler = new CharsetHandler('phptoflash');
  35. $this->rsCharsetHandler = new CharsetHandler('sqltoflash');
  36. $this->resourceObjects = $GLOBALS['amfphp']['adapterMappings'];
  37. $this->native = $GLOBALS['amfphp']['native'] && function_exists('amf_decode');
  38. $this->encodeFlags = (AMFPHP_BIG_ENDIAN?2:0) |
  39. ($GLOBALS['amfphp']['encoding'] == 'amf3' ? 1:0);
  40. }
  41. /**
  42. * serialize is the run method of the class. When serialize is called
  43. * the AMFObject passed in is read and converted into the amf binary
  44. * representing the PHP data represented.
  45. *
  46. * @param object $d the AMFObject to serialize
  47. */
  48. function serialize(&$amfout) {
  49. $encodeCallback = array(&$this,"encodeCallback");
  50. $this->writeInt(0); // write the version ???
  51. $count = $amfout->numOutgoingHeader();
  52. $this->writeInt($count); // write header count
  53. for ($i = 0; $i < $count; $i++) {
  54. //write headers
  55. $header = &$amfout->getOutgoingHeaderAt($i);
  56. $this->writeUTF($header->name);
  57. $this->writeByte(0);
  58. $tempBuf = $this->outBuffer;
  59. $this->outBuffer = "";
  60. if($this->native)
  61. $this->outBuffer .= amf_encode($header->value,$this->encodeFlags, $encodeCallback);
  62. else
  63. $this->writeData($header->value);
  64. $tempBuf2 = $this->outBuffer;
  65. $this->outBuffer = $tempBuf;
  66. $this->writeLong(strlen($tempBuf2));
  67. $this->outBuffer .= $tempBuf2;
  68. }
  69. $count = $amfout->numBody();
  70. $this->writeInt($count); // write the body count
  71. for ($i = 0; $i < $count; $i++) {
  72. //write body
  73. $this->amf0StoredObjects = array();
  74. $this->storedStrings = array();
  75. $this->storedObjects = array();
  76. $this->encounteredStrings = 0;
  77. $this->storedDefinitions = 0;
  78. $body = &$amfout->getBodyAt($i);
  79. $this->currentBody = & $body;
  80. $this->writeUTF($body->responseURI); // write the responseURI header
  81. $this->writeUTF($body->responseTarget); // write null, haven't found another use for this
  82. $tempBuf = $this->outBuffer;
  83. $this->outBuffer = "";
  84. if($this->native)
  85. $this->outBuffer .= amf_encode($body->getResults(),$this->encodeFlags, $encodeCallback);
  86. else
  87. $this->writeData($body->getResults());
  88. $tempBuf2 = $this->outBuffer;
  89. $this->outBuffer = $tempBuf;
  90. $this->writeLong(strlen($tempBuf2));
  91. $this->outBuffer .= $tempBuf2;
  92. }
  93. return $this->outBuffer;
  94. }
  95. function encodeCallback($value)
  96. {
  97. ///print_r($value);
  98. if(is_object($value))
  99. {
  100. $className = strtolower(get_class($value));
  101. if(AMFPHP_PHP5 && $className == 'domdocument')
  102. {
  103. return array($this->cleanXml($value->saveXml()),1);
  104. }
  105. else if(array_key_exists($className, $GLOBALS['amfphp']['adapterMappings']))
  106. {
  107. $subtype = $GLOBALS['amfphp']['adapterMappings'][strtolower($className)];
  108. $classname = $subtype . "Adapter"; // full class name
  109. $includeFile = include_once(AMFPHP_BASE . "shared/adapters/" . $classname . ".php"); // try to load the recordset library from the sql folder
  110. if (!$includeFile) {
  111. trigger_error("The recordset filter class " . $classname . " was not found", E_USER_ERROR);
  112. }
  113. $recordSet = new $classname($value); // returns formatted recordset
  114. return array(
  115. array("__amf_recordset__" => 2,
  116. "rows" => $recordSet->rows,
  117. "columns" => $recordSet->columns),
  118. 5);
  119. }
  120. else if(AMFPHP_PHP5 == 0 && $className == 'domdocument')
  121. {
  122. return array($this->cleanXml($value->dump_mem()),1);
  123. }
  124. else if($className == 'simplexmlelement')
  125. {
  126. return array($this->cleanXml($value->asXML()),1);
  127. }
  128. elseif($className == 'bytearray' && $this->encodeFlags & 1 == 1)
  129. {
  130. return array($value->data, 7);
  131. }
  132. else
  133. {
  134. $className = $this->getClassName($value);
  135. return array($value,3,$className);
  136. }
  137. }
  138. else
  139. {
  140. //A resource
  141. $type = get_resource_type($value);
  142. list($type, $subtype) = $this->sanitizeType($type);
  143. $classname = $subtype . "Adapter"; // full class name
  144. $includeFile = include_once(AMFPHP_BASE . "shared/adapters/" . $classname . ".php"); // try to load the recordset library from the sql folder
  145. if (!$includeFile) {
  146. trigger_error("The recordset filter class " . $classname . " was not found", E_USER_ERROR);
  147. }
  148. $recordSet = new $classname($value); // returns formatted recordset
  149. return array(
  150. array("__amf_recordset__" => 2,
  151. "rows" => $recordSet->rows,
  152. "columns" => $recordSet->columns),
  153. 5);
  154. }
  155. }
  156. function cleanXml($d)
  157. {
  158. return preg_replace('/\>(\n|\r|\r\n| |\t)*\</','><',trim($d));
  159. }
  160. /**********************************************************************************
  161. * This code used to be in AMFOutputStream
  162. ********************************************************************************/
  163. /**
  164. * writeByte writes a singe byte to the output stream
  165. * 0-255 range
  166. *
  167. * @param int $b An int that can be converted to a byte
  168. */
  169. function writeByte($b) {
  170. $this->outBuffer .= pack("c", $b); // use pack with the c flag
  171. }
  172. /**
  173. * writeInt takes an int and writes it as 2 bytes to the output stream
  174. * 0-65535 range
  175. *
  176. * @param int $n An integer to convert to a 2 byte binary string
  177. */
  178. function writeInt($n) {
  179. $this->outBuffer .= pack("n", $n); // use pack with the n flag
  180. }
  181. /**
  182. * writeLong takes an int, float or double and converts it to a 4 byte binary string and
  183. * adds it to the output buffer
  184. *
  185. * @param long $l A long to convert to a 4 byte binary string
  186. */
  187. function writeLong($l) {
  188. $this->outBuffer .= pack("N", $l); // use pack with the N flag
  189. }
  190. /**
  191. * writeUTF takes and input string, writes the length as an int and then
  192. * appends the string to the output buffer
  193. *
  194. * @param string $s The string less than 65535 characters to add to the stream
  195. */
  196. function writeUTF($s) {
  197. $os = $this->charsetHandler->transliterate($s);
  198. $this->writeInt(strlen($os)); // write the string length - max 65535
  199. $this->outBuffer .= $os; // write the string chars
  200. }
  201. /**
  202. * writeBinary takes and input string, writes the length as an int and then
  203. * appends the string to the output buffer
  204. *
  205. * @param string $s The string less than 65535 characters to add to the stream
  206. */
  207. function writeBinary($s) {
  208. $this->outBuffer .= $s; // write the string chars
  209. }
  210. /**
  211. * writeLongUTF will write a string longer than 65535 characters.
  212. * It works exactly as writeUTF does except uses a long for the length
  213. * flag.
  214. *
  215. * @param string $s A string to add to the byte stream
  216. */
  217. function writeLongUTF($s) {
  218. $os = $this->charsetHandler->transliterate($s);
  219. $this->writeLong(strlen($os));
  220. $this->outBuffer .= $os; // write the string chars
  221. }
  222. /**
  223. * writeDouble takes a float as the input and writes it to the output stream.
  224. * Then if the system is big-endian, it reverses the bytes order because all
  225. * doubles passed via remoting are passed little-endian.
  226. *
  227. * @param double $d The double to add to the output buffer
  228. */
  229. function writeDouble($d) {
  230. $b = pack("d", $d); // pack the bytes
  231. if ($this->isBigEndian) { // if we are a big-endian processor
  232. $r = strrev($b);
  233. } else { // add the bytes to the output
  234. $r = $b;
  235. }
  236. $this->outBuffer .= $r;
  237. }
  238. function sanitizeType($type)
  239. {
  240. $subtype = -1;
  241. $type = strtolower($type);
  242. if($type == NULL || trim($type) == "")
  243. {
  244. $type = -1;
  245. }
  246. if(strpos($type, ' ') !== false)
  247. {
  248. $str = explode(' ', $type);
  249. if(in_array($str[1], array("result", 'resultset', "recordset", "statement")))
  250. {
  251. $type = "__RECORDSET__";
  252. $subtype = $str[0];
  253. }
  254. }
  255. return array($type, $subtype);
  256. }
  257. function getClassName(&$d)
  258. {
  259. $classname = get_class($d);
  260. if(strtolower($classname) == 'stdclass' && !isset($d->_explicitType) )
  261. {
  262. return "";
  263. }
  264. if(isset($d->_explicitType))
  265. {
  266. $type = $d->_explicitType;
  267. unset($d->_explicitType);
  268. return $type;
  269. }
  270. if(isset($GLOBALS['amfphp']['outgoingClassMappings'][strtolower($classname)]))
  271. {
  272. return $GLOBALS['amfphp']['outgoingClassMappings'][strtolower($classname)];
  273. }
  274. if(class_exists("ReflectionClass")) //Another way of doing things, by Renaun Erickson
  275. {
  276. $reflectionClass = new ReflectionClass( $classname );
  277. $fileName = $reflectionClass->getFileName();
  278. $basePath = $GLOBALS['amfphp']['customMappingsPath'];
  279. if( $basePath == "" )
  280. $basePath = getcwd();
  281. // Handle OS filesystem differences
  282. if( DIRECTORY_SEPARATOR == "\\" && ( strpos( $basePath, DIRECTORY_SEPARATOR ) === false ) )
  283. $basePath = str_replace( "/", DIRECTORY_SEPARATOR, $basePath );
  284. if(strpos($fileName, $basePath) === FALSE)
  285. {
  286. return $classname;
  287. }
  288. $fullClassName = substr( $fileName, strpos( $fileName, $basePath ) );
  289. $fullClassName = substr( $fullClassName, strlen( $basePath ) );
  290. $fullClassName = substr( $fullClassName, 0, strlen( $fullClassName ) - 4 );
  291. $fullClassName = str_replace( DIRECTORY_SEPARATOR, '.', $fullClassName );
  292. return $fullClassName;
  293. }
  294. return $classname;
  295. }
  296. }
  297. ?>