/** * Given the raw bytes containing the property-flags and * property-list from a content-frame-header, parse and insert * into a dictionary stored in this object as an attribute named * 'properties'. */ public function load_properties($raw_bytes) { $r = new AMQPReader($raw_bytes); // Read 16-bit shorts until we get one with a low bit set to zero $flags = array(); while (true) { $flag_bits = $r->read_short(); $flags[] = $flag_bits; if (($flag_bits & 1) == 0) { break; } } $shift = 0; $d = array(); foreach ($this->prop_types as $key => $proptype) { if ($shift == 0) { if (!$flags) { break; } $flag_bits = array_shift($flags); $shift = 15; } if ($flag_bits & 1 << $shift) { $d[$key] = $r->{'read_' . $proptype}(); } $shift -= 1; } $this->properties = $d; }
/** * @dataProvider propertiesDataProvider */ public function testSerializeProperties(array $expected, array $properties) { /** @var AMQPReader $reader */ $reader = new AMQPReader(null); /** @var AMQPMessage $message */ $message = new AMQPMessage('', $properties); /** @var string $encodedData */ $encodedData = $message->serialize_properties(); // Bypasses the network part and injects the encoded data into the reader $reader->reuse($encodedData); // Injects the reader into the message $message->load_properties($reader); $this->assertEquals($expected, $message->get_properties()); }
/** * @return AMQPMessage * @throws \PhpAmqpLib\Exception\AMQPRuntimeException */ public function wait_content() { list($frame_type, $payload) = $this->next_frame(); $this->validate_header_frame($frame_type); $this->wait_content_reader->reuse(mb_substr($payload, 0, 12, 'ASCII')); // $payload_reader = new AMQPReader(substr($payload,0,12)); $class_id = $this->wait_content_reader->read_short(); $weight = $this->wait_content_reader->read_short(); $body_size = $this->wait_content_reader->read_longlong(); //hack to avoid creating new instances of AMQPReader; $this->msg_property_reader->reuse(mb_substr($payload, 12, mb_strlen($payload, 'ASCII') - 12, 'ASCII')); $msg = new AMQPMessage(); $msg->load_properties($this->msg_property_reader); $msg->body_size = $body_size; list($msg_body, $is_truncated) = $this->build_msg_body($body_size); $msg->body = $msg_body; $msg->is_truncated = $is_truncated; if ($this->auto_decode && isset($msg->content_encoding)) { try { $msg->body = $msg->body->decode($msg->content_encoding); } catch (\Exception $e) { $this->debug->debug_msg('Ignoring body decoding exception: ' . $e->getMessage()); } } return $msg; }
public function wait_content() { $frm = $this->next_frame(); $frame_type = $frm[0]; $payload = $frm[1]; if ($frame_type != 2) { throw new AMQPRuntimeException("Expecting Content header"); } $payload_reader = new AMQPReader(substr($payload, 0, 12)); $class_id = $payload_reader->read_short(); $weight = $payload_reader->read_short(); $body_size = $payload_reader->read_longlong(); $msg = new AMQPMessage(); $msg->load_properties(substr($payload, 12)); $body_parts = array(); $body_received = 0; while (bccomp($body_size, $body_received) == 1) { $frm = $this->next_frame(); $frame_type = $frm[0]; $payload = $frm[1]; if ($frame_type != 3) { throw new AMQPRuntimeException("Expecting Content body, received frame type {$frame_type} (" . self::$FRAME_TYPES[$frame_type] . ")"); } $body_parts[] = $payload; $body_received = bcadd($body_received, strlen($payload)); } $msg->body = implode("", $body_parts); if ($this->auto_decode && isset($msg->content_encoding)) { try { $msg->body = $msg->body->decode($msg->content_encoding); } catch (\Exception $e) { if ($this->debug) { MiscHelper::debug_msg("Ignoring body decoding exception: " . $e->getMessage()); } } } return $msg; }
/** * @return AMQPMessage * @throws \PhpAmqpLib\Exception\AMQPRuntimeException */ public function wait_content() { $frm = $this->next_frame(); $frame_type = $frm[0]; $payload = $frm[1]; if ($frame_type != 2) { throw new AMQPRuntimeException('Expecting Content header'); } $this->wait_content_reader->reuse(mb_substr($payload, 0, 12, 'ASCII')); // $payload_reader = new AMQPReader(substr($payload,0,12)); $class_id = $this->wait_content_reader->read_short(); $weight = $this->wait_content_reader->read_short(); $body_size = $this->wait_content_reader->read_longlong(); //hack to avoid creating new instances of AMQPReader; $this->msg_property_reader->reuse(mb_substr($payload, 12, mb_strlen($payload, 'ASCII') - 12, 'ASCII')); $msg = new AMQPMessage(); $msg->load_properties($this->msg_property_reader); $msg->body_size = $body_size; $body_parts = array(); $body_received = 0; while (bccomp($body_size, $body_received, 0) == 1) { $frm = $this->next_frame(); $frame_type = $frm[0]; $payload = $frm[1]; if ($frame_type != 3) { $PROTOCOL_CONSTANTS_CLASS = self::$PROTOCOL_CONSTANTS_CLASS; throw new AMQPRuntimeException(sprintf('Expecting Content body, received frame type %s (%s)', $frame_type, $PROTOCOL_CONSTANTS_CLASS::$FRAME_TYPES[$frame_type])); } $body_received = bcadd($body_received, mb_strlen($payload, 'ASCII'), 0); if (!is_null($this->body_size_max) && $body_received > $this->body_size_max) { $msg->is_truncated = true; continue; } $body_parts[] = $payload; } $msg->body = implode('', $body_parts); if ($this->auto_decode && isset($msg->content_encoding)) { try { $msg->body = $msg->body->decode($msg->content_encoding); } catch (\Exception $e) { if ($this->debug) { MiscHelper::debug_msg('Ignoring body decoding exception: ' . $e->getMessage()); } } } return $msg; }
/** * @param AMQPReader $reader * @return array */ public static function basicGetEmpty(AMQPReader $reader) { $response = array(); $response[] = $reader->read_shortstr(); return $response; }
/** * Returns a failed message * * @param AMQPReader $args * @param AMQPMessage $msg */ protected function basic_return($args, $msg) { $reply_code = $args->read_short(); $reply_text = $args->read_shortstr(); $exchange = $args->read_shortstr(); $routing_key = $args->read_shortstr(); if (null !== $this->basic_return_callback) { call_user_func_array($this->basic_return_callback, array($reply_code, $reply_text, $exchange, $routing_key, $msg)); } elseif ($this->debug) { MiscHelper::debug_msg('Skipping unhandled basic_return message'); } }
/** * Read an AMQP table, and return as a PHP array. keys are strings, * values are (type,value) tuples. */ public function read_table() { $this->bitcount = $this->bits = 0; $tlen = $this->read_php_int(); if ($tlen < 0) { throw new AMQPOutOfBoundsException("Table is longer than supported"); } $table_data = new AMQPReader($this->rawread($tlen), null); $result = array(); while ($table_data->tell() < $tlen) { $name = $table_data->read_shortstr(); $ftype = $table_data->rawread(1); $val = $table_data->read_value($ftype); $result[$name] = array($ftype, $val); } return $result; }
/** * Returns a failed message * * @param AMQPReader $reader * @param AMQPMessage $message * @return null */ protected function basic_return($reader, $message) { $callback = $this->basic_return_callback; if (!is_callable($callback)) { $this->debug->debug_msg('Skipping unhandled basic_return message'); return null; } $reply_code = $reader->read_short(); $reply_text = $reader->read_shortstr(); $exchange = $reader->read_shortstr(); $routing_key = $reader->read_shortstr(); call_user_func_array($callback, array($reply_code, $reply_text, $exchange, $routing_key, $message)); }
/** * @param AMQPReader $reader * @return array */ public static function testContentOk(AMQPReader $reader) { $response = array(); $response[] = $reader->read_long(); return $response; }
protected function basic_cancel_from_server(AMQPReader $args) { $consumerTag = $args->read_shortstr(); throw new AMQPBasicCancelException($consumerTag); }
/** * Read an AMQP table, and return as a PHP array. keys are strings, * values are (type,value) tuples. * * @param bool $returnObject Whether to return AMQPArray instance instead of plain array * @return array|AMQPTable */ public function read_table($returnObject = false) { $this->bitcount = $this->bits = 0; $tlen = $this->read_php_int(); if ($tlen < 0) { throw new AMQPOutOfBoundsException('Table is longer than supported'); } $table_data = new AMQPReader($this->rawread($tlen), null); $result = $returnObject ? new AMQPTable() : array(); while ($table_data->tell() < $tlen) { $name = $table_data->read_shortstr(); $ftype = AMQPAbstractCollection::getDataTypeForSymbol($ftypeSym = $table_data->rawread(1)); $val = $table_data->read_value($ftype, $returnObject); $returnObject ? $result->set($name, $val, $ftype) : ($result[$name] = array($ftypeSym, $val)); } return $result; }
/** * @param AMQPReader $args * @return array */ public static function basicGetEmpty($args) { $ret = array(); $ret[] = $args->read_shortstr(); return $ret; }
public function testTableWriteReadCollection() { $w = new AMQPWriter(); $w->write_table(new AMQPTable(array('long' => 12345, 'long_neg' => -12345, 'longlong' => 3000000000, 'longlong_neg' => -3000000000, 'float_low' => 9.2233720368548, 'float_high' => (double) 9.2233720368548E+18, 'bool_true' => true, 'bool_false' => false, 'array' => array(1, 2, 3, 'foo', array('bar' => 'baz'), array('boo', false, 5), true), 'array_empty' => array(), 'table' => array('foo' => 'bar', 'baz' => 'boo', 'bool' => true, 'tbl' => array('bar' => 'baz'), 'arr' => array('boo', false, 5)), 'table_num' => array(1 => 5, 3 => 'foo', 786 => 674), 'array_nested' => array(1, array(2, array(3, array(4)))), 'table_nested' => array('i' => 1, 'n' => array('i' => 2, 'n' => array('i' => 3, 'n' => array('i' => 4))))))); $r = new AMQPReader($w->getvalue()); //type casting - thanks to ancient phpunit on travis $this->assertEquals(array('long' => 12345, 'long_neg' => -12345, 'longlong' => (string) 3000000000, 'longlong_neg' => (string) -3000000000, 'float_low' => (string) (double) 9.2233720368548, 'float_high' => (string) (double) 9.2233720368548E+18, 'bool_true' => true, 'bool_false' => false, 'array' => array(1, 2, 3, 'foo', array('bar' => 'baz'), array('boo', false, 5), true), 'array_empty' => array(), 'table' => array('foo' => 'bar', 'baz' => 'boo', 'bool' => true, 'tbl' => array('bar' => 'baz'), 'arr' => array('boo', false, 5)), 'table_num' => array(1 => 5, 3 => 'foo', 786 => 674), 'array_nested' => array(1, array(2, array(3, array(4)))), 'table_nested' => array('i' => 1, 'n' => array('i' => 2, 'n' => array('i' => 3, 'n' => array('i' => 4))))), $r->read_table(true)->getNativeData()); }
/** * @param AMQPReader $propertyReader * @param AMQPReader $contentReader * @return \PhpAmqpLib\Message\AMQPMessage */ protected function createMessage($propertyReader, $contentReader) { $bodyChunks = array(); $bodyReceivedBytes = 0; $message = new AMQPMessage(); $message->load_properties($propertyReader)->setBodySize($contentReader->read_longlong()); while (bccomp($message->getBodySize(), $bodyReceivedBytes, 0) == 1) { list($frame_type, $payload) = $this->next_frame(); $this->validate_body_frame($frame_type); $bodyReceivedBytes = bcadd($bodyReceivedBytes, mb_strlen($payload, 'ASCII'), 0); if (is_int($this->maxBodySize) && $bodyReceivedBytes > $this->maxBodySize) { $message->setIsTruncated(true); continue; } $bodyChunks[] = $payload; } $message->setBody(implode('', $bodyChunks)); $messageEncoding = $message->getContentEncoding(); if ($this->auto_decode && !empty($messageEncoding)) { try { // Where does the decode() method come from if body is a string? $decodedBody = $message->getBody()->decode($messageEncoding); $message->setBody($decodedBody); } catch (\Exception $e) { $this->debug->debug_msg('Ignoring body decoding exception: ' . $e->getMessage()); } } return $message; }
/** * @param AMQPReader $args * @return array */ public static function testContentOk($args) { $ret = array(); $ret[] = $args->read_long(); return $ret; }
/** * Handles connection blocked notifications * * @param AMQPReader $args */ protected function connection_blocked(AMQPReader $args) { // Call the block handler and pass in the reason $this->dispatch_to_handler($this->connection_block_handler, array($args->read_shortstr())); }
/** * @param AMQPReader $propertyReader * @param AMQPReader $contentReader * @return \PhpAmqpLib\Message\AMQPMessage */ protected function createMessage($propertyReader, $contentReader) { $bodyChunks = array(); $bodyReceivedBytes = 0; $message = new AMQPMessage(); $message->load_properties($propertyReader)->setBodySize($contentReader->read_longlong()); while (bccomp($message->getBodySize(), $bodyReceivedBytes, 0) == 1) { list($frame_type, $payload) = $this->next_frame(); $this->validate_body_frame($frame_type); $bodyReceivedBytes = bcadd($bodyReceivedBytes, mb_strlen($payload, 'ASCII'), 0); if (is_int($this->maxBodySize) && $bodyReceivedBytes > $this->maxBodySize) { $message->setIsTruncated(true); continue; } $bodyChunks[] = $payload; } $message->setBody(implode('', $bodyChunks)); return $message; }