/** * Writes numeric values for int, uint and double (floating point) vectors to the AMF byte stream. * * @param mixed But should be either an integer (signed or unsigned) or a floating point. * @param string 'i' for signed integers, 'I' for unsigned integers, and 'd' for double precision floating point */ function writeAmf3VectorValue($value, $format) { $bytes = pack($format, $value); if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { $bytes = strrev($bytes); } $this->outBuffer .= $bytes; }
/** * @todo Is the reference still needed? PHP4 needed it for objects, but PHP5 always * passes objects by reference. And PHP5 uses a copy-on-write approach, so that all * values are passed as 'reference', in case no changes take place. * * @todo no type markers ("\6', for example) in this method! */ protected function writeAmf3Data($d) { if (is_int($d)) { //int $this->writeAmf3Number($d); return; } elseif (is_float($d)) { //double $this->outBuffer .= ""; $this->writeDouble($d); return; } elseif (is_string($d)) { // string $this->outBuffer .= ""; $this->writeAmf3String($d); return; } elseif (is_bool($d)) { // boolean $this->writeAmf3Bool($d); return; } elseif (is_null($d)) { // null $this->writeAmf3Null(); return; } elseif (Amfphp_Core_Amf_Util::is_undefined($d)) { // undefined $this->writeAmf3Undefined(); return; } elseif (Amfphp_Core_Amf_Util::is_date($d)) { // date $this->writeAmf3Date($d); return; } elseif (is_array($d)) { // array $this->writeAmf3Array($d); return; } elseif (Amfphp_Core_Amf_Util::is_byteArray($d)) { //byte array $this->writeAmf3ByteArray($d->data); return; } elseif (Amfphp_Core_Amf_Util::is_Xml($d)) { // Xml $this->writeAmf3Xml($d); return; } elseif (Amfphp_Core_Amf_Util::is_XmlDocument($d)) { // XmlDoc $this->writeAmf3XmlDocument($d); return; } elseif (is_object($d)) { $explicitTypeField = Amfphp_Core_Amf_Constants::FIELD_EXPLICIT_TYPE; if (isset($d->{$explicitTypeField})) { $this->writeAmf3TypedObject($d); return; } else { $this->writeAmf3AnonymousObject($d); return; } } throw new Amfphp_Core_Exception("couldn't write object " . print_r($d, false)); }
/** * @todo Is the reference still needed? PHP4 needed it for objects, but PHP5 always * passes objects by reference. And PHP5 uses a copy-on-write approach, so that all * values are passed as "reference", in case no changes take place. * * @todo no type markers ("\6", for example) in this method! */ protected function writeAmf3Data(&$d) { if (is_int($d)) { //int $this->writeAmf3Number($d); return; } elseif (is_float($d)) { //double $this->outBuffer .= ""; $this->writeDouble($d); return; } elseif (is_string($d)) { // string $this->outBuffer .= ""; $this->writeAmf3String($d); return; } elseif (is_bool($d)) { // boolean $this->writeAmf3Bool($d); return; } elseif (is_null($d)) { // null $this->writeAmf3Null(); return; } elseif (Amfphp_Core_Amf_Util::is_undefined($d)) { // undefined $this->writeAmf3Undefined(); return; } elseif (Amfphp_Core_Amf_Util::is_date($d)) { // date $this->writeAmf3Date($d); return; } elseif (is_array($d)) { // array $this->writeAmf3Array($d); return; } elseif (Amfphp_Core_Amf_Util::is_byteArray($d)) { //byte array $this->writeAmf3ByteArray($d->data); return; } elseif (Amfphp_Core_Amf_Util::is_Xml($d)) { // Xml $this->writeAmf3Xml($d); return; } elseif (Amfphp_Core_Amf_Util::is_XmlDocument($d)) { // XmlDoc $this->writeAmf3XmlDocument($d); return; } elseif (is_object($d)) { $this->writeAmf3Object($d); return; } throw new Amfphp_Core_Exception("couldn't write object " . print_r($d, false)); }
/** * looks at the response and sets the explicit type field so that the serializer sends it properly * @param mixed $deserializedResponse * @return mixed */ public function filterDeserializedResponse($deserializedResponse) { $deserializedResponse = Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($deserializedResponse, array($this, 'convertStringFromPhpToClientCharsets')); if (class_exists('AmfphpMonitor', false)) { AmfphpMonitor::addTime('Response Charset Conversion'); } return $deserializedResponse; }
/** * readDouble reads the floating point value from the bytes stream and properly orders * the bytes depending on the system architecture. * * @return float The floating point value of the next 8 bytes */ protected function readDouble() { $bytes = substr($this->rawData, $this->currentByte, 8); $this->currentByte += 8; if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { $bytes = strrev($bytes); } $zz = unpack('dflt', $bytes); // unpack the bytes return $zz['flt']; // return the number from the associative array }
/** * build date */ public function buildDate() { $this->dDate = new Amfphp_Core_Amf_Types_Date(1306926779576); //1st June 2011 //type: 0x0B $this->sDate = pack('C', 0xb); //date is a double, see writeDouble for little/big endian $dateData = pack('d', 1306926779576); if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { $dateData = strrev($dateData); } $this->sDate .= $dateData; //time zone, not supported. int set to 0 $this->sDate .= pack('n', 0); }
/** * looks at the outgoing packet and sets the explicit type field so that the serializer sends it properly * @param mixed $deserializedResponse * @return mixed */ public function filterDeserializedResponse($deserializedResponse) { $ret = null; if ($this->scanEnabled) { $ret = Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($deserializedResponse, array($this, 'markExplicitType')); } if (class_exists('AmfphpMonitor', false)) { AmfphpMonitor::addTime('Response Value Object Conversion'); } return $ret; }
/** * looks at the outgoing packet and sets the explicit type field so that the serializer sends it properly * @param mixed $deserializedResponse * @return mixed */ public function filterDeserializedResponse($deserializedResponse) { $deserializedResponse = Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($deserializedResponse, array($this, "markExplicitType")); return $deserializedResponse; }
/** * revers packed data if big endian * @see Amfphp_Core_Amf_Util * @param string $packedData * @return string */ private function revIfBigEndian($packedData) { if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { return strrev($packedData); } else { return $packedData; } }
/** * Read numeric values from the AMF byte stream. Please be aware that unsigned integers are not really supported in PHP, and for this reason * unsigned integers are cast to float. {@link http://php.net/manual/en/language.types.integer.php}. * * @param integer You can specify 4 for integers or 8 for double precision floating point. * @param string 'ival' for signed integers, 'Ival' for unsigned integers, and "dval" for double precision floating point * * @return <type> */ protected function readAmf3VectorValue($length, $format) { $bytes = $this->readBuffer($length); if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { $bytes = strrev($bytes); } $array = unpack($format, $bytes); // Unsigned Integers don't work in PHP amazingly enough. If you go into the "upper" region // on the Actionscript side, this will come through as a negative without this cast to a float // see http://php.net/manual/en/language.types.integer.php if ($format === "Ival") { $array["val"] = floatval(sprintf('%u', $array["val"])); } return $array["val"]; }
/** * looks at the response and sets the explicit type field so that the serializer sends it properly * @param mixed $deserializedResponse * @return mixed */ public function filterDeserializedResponse($deserializedResponse) { $deserializedResponse = Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($deserializedResponse, array($this, "convertStringFromPhpToClientCharsets")); return $deserializedResponse; }
/** * test apply function to contained objects */ public function testApplyFunctionToContainedObjects() { //non object $this->counter = 0; Amfphp_Core_Amf_Util::applyFunctionToContainedObjects('bla', array($this, 'testApplyFunc')); $this->assertEquals(1, $this->counter); //simple $testObj1 = array(); $testObj1[] = new stdClass(); $this->counter = 0; Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($testObj1, array($this, 'testApplyFunc')); $this->assertEquals(2, $this->counter); //a bit more complicated $testObj2 = new stdClass(); $subObj = array(new stdClass(), new stdClass(), array(1, 2, false), null); $testObj2->data = $subObj; $testObj2->bla = 'bla'; $this->counter = 0; Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($testObj2, array($this, 'testApplyFunc')); $this->assertEquals(10, $this->counter); }
/** * looks at the outgoing packet and sets the explicit type field so that the serializer sends it properly * @param mixed $deserializedResponse * @return mixed */ public function filterDeserializedResponse($deserializedResponse) { $deserializedResponse = Amfphp_Core_Amf_Util::applyFunctionToContainedObjects($deserializedResponse, array($this, 'markExplicitType')); // file_put_contents("rawdata.txt", serialize($deserializedResponse)); return $deserializedResponse; }
/** * build date */ public function buildDate() { $this->dDate = new Amfphp_Core_Amf_Types_Date(1306926779576); //1st June 2011 //type: 0x08 $this->sDate = pack('C', 0x8); //U29D-value = 1. Marker to distinguish from references, I think $this->sDate .= pack('C', 0x1); //date is a double, see writeDouble for little/big endian $dateData = pack('d', 1306926779576); if (Amfphp_Core_Amf_Util::isSystemBigEndian()) { $dateData = strrev($dateData); } $this->sDate .= $dateData; }