/** * Determine type and serialize accordingly * * Checks to see if the type was declared and then either * auto negotiates the type or relies on the user defined markerType to * serialize the data into amf * * @param mixed $data * @param mixed $markerType * @param mixed $dataByVal * @return Serializer * @throws Amf\Exception\ExceptionInterface for unrecognized types or data */ public function writeTypeMarker(&$data, $markerType = null, $dataByVal = false) { // Workaround for PHP5 with E_STRICT enabled complaining about "Only // variables should be passed by reference" if (null === $data && $dataByVal !== false) { $data =& $dataByVal; } if (null !== $markerType) { //try to reference the given object if (!$this->writeObjectReference($data, $markerType)) { // Write the Type Marker to denote the following action script data type $this->_stream->writeByte($markerType); switch ($markerType) { case Amf\Constants::AMF0_NUMBER: $this->_stream->writeDouble($data); break; case Amf\Constants::AMF0_BOOLEAN: $this->_stream->writeByte($data); break; case Amf\Constants::AMF0_STRING: $this->_stream->writeUTF($data); break; case Amf\Constants::AMF0_OBJECT: $this->writeObject($data); break; case Amf\Constants::AMF0_NULL: break; case Amf\Constants::AMF0_REFERENCE: $this->_stream->writeInt($data); break; case Amf\Constants::AMF0_MIXEDARRAY: // Write length of numeric keys as zero. $this->_stream->writeLong(0); $this->writeObject($data); break; case Amf\Constants::AMF0_ARRAY: $this->writeArray($data); break; case Amf\Constants::AMF0_DATE: $this->writeDate($data); break; case Amf\Constants::AMF0_LONGSTRING: $this->_stream->writeLongUTF($data); break; case Amf\Constants::AMF0_TYPEDOBJECT: $this->writeTypedObject($data); break; case Amf\Constants::AMF0_AMF3: $this->writeAmf3TypeMarker($data); break; default: throw new Amf\Exception\InvalidArgumentException("Unknown Type Marker: " . $markerType); } } } else { if (is_resource($data)) { $data = Parser\TypeLoader::handleResource($data); } switch (true) { case is_int($data) || is_float($data): $markerType = Amf\Constants::AMF0_NUMBER; break; case is_bool($data): $markerType = Amf\Constants::AMF0_BOOLEAN; break; case is_string($data) && strlen($data) > 65536: $markerType = Amf\Constants::AMF0_LONGSTRING; break; case is_string($data): $markerType = Amf\Constants::AMF0_STRING; break; case is_object($data): if ($data instanceof DateTime) { $markerType = Amf\Constants::AMF0_DATE; } else { if ($className = $this->getClassName($data)) { //Object is a Typed object set classname $markerType = Amf\Constants::AMF0_TYPEDOBJECT; $this->_className = $className; } else { // Object is a generic classname $markerType = Amf\Constants::AMF0_OBJECT; } break; } break; case null === $data: $markerType = Amf\Constants::AMF0_NULL; break; case is_array($data): // check if it is an associative array $i = 0; foreach (array_keys($data) as $key) { // check if it contains non-integer keys if (!is_numeric($key) || intval($key) != $key) { $markerType = Amf\Constants::AMF0_OBJECT; break; // check if it is a sparse indexed array } elseif ($key != $i) { $markerType = Amf\Constants::AMF0_MIXEDARRAY; break; } $i++; } // Dealing with a standard numeric array if (!$markerType) { $markerType = Amf\Constants::AMF0_ARRAY; break; } break; default: throw new Amf\Exception\InvalidArgumentException('Unsupported data type: ' . gettype($data)); } $this->writeTypeMarker($data, $markerType); } return $this; }
/** * Serialize PHP types to AMF3 and write to stream * * Checks to see if the type was declared and then either * auto negotiates the type or use the user defined markerType to * serialize the data from php back to AMF3 * * @param mixed $data * @param int $markerType * @param mixed $dataByVal * @throws Parser\Exception\ExceptionInterface * @return void */ public function writeTypeMarker(&$data, $markerType = null, $dataByVal = false) { // Workaround for PHP5 with E_STRICT enabled complaining about "Only // variables should be passed by reference" if (null === $data && $dataByVal !== false) { $data =& $dataByVal; } if (null !== $markerType) { // Write the Type Marker to denote the following action script data type $this->_stream->writeByte($markerType); switch ($markerType) { case Amf\Constants::AMF3_NULL: break; case Amf\Constants::AMF3_BOOLEAN_FALSE: break; case Amf\Constants::AMF3_BOOLEAN_TRUE: break; case Amf\Constants::AMF3_INTEGER: $this->writeInteger($data); break; case Amf\Constants::AMF3_NUMBER: $this->_stream->writeDouble($data); break; case Amf\Constants::AMF3_STRING: $this->writeString($data); break; case Amf\Constants::AMF3_DATE: $this->writeDate($data); break; case Amf\Constants::AMF3_ARRAY: $this->writeArray($data); break; case Amf\Constants::AMF3_OBJECT: $this->writeObject($data); break; case Amf\Constants::AMF3_BYTEARRAY: $this->writeByteArray($data); break; case Amf\Constants::AMF3_XMLSTRING: $this->writeXml($data); break; default: throw new Parser\Exception\OutOfBoundsException('Unknown Type Marker: ' . $markerType); } } else { // Detect Type Marker if (is_resource($data)) { $data = Parser\TypeLoader::handleResource($data); } switch (true) { case null === $data: $markerType = Amf\Constants::AMF3_NULL; break; case is_bool($data): if ($data) { $markerType = Amf\Constants::AMF3_BOOLEAN_TRUE; } else { $markerType = Amf\Constants::AMF3_BOOLEAN_FALSE; } break; case is_int($data): if ($data > 0xfffffff || $data < -268435456) { $markerType = Amf\Constants::AMF3_NUMBER; } else { $markerType = Amf\Constants::AMF3_INTEGER; } break; case is_float($data): $markerType = Amf\Constants::AMF3_NUMBER; break; case is_string($data): $markerType = Amf\Constants::AMF3_STRING; break; case is_array($data): $markerType = Amf\Constants::AMF3_ARRAY; break; case is_object($data): // Handle object types. if ($data instanceof DateTime) { $markerType = Amf\Constants::AMF3_DATE; } elseif ($data instanceof Value\ByteArray) { $markerType = Amf\Constants::AMF3_BYTEARRAY; } elseif ($data instanceof DOMDocument || $data instanceof SimpleXMLElement) { $markerType = Amf\Constants::AMF3_XMLSTRING; } else { $markerType = Amf\Constants::AMF3_OBJECT; } break; default: throw new Parser\Exception\OutOfBoundsException('Unsupported data type: ' . gettype($data)); } $this->writeTypeMarker($data, $markerType); } }