/** * 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($rawBytes) { $reader = new Reader($rawBytes); $flagBits = false; // Read 16-bit shorts until we get one with a low bit set to zero $flags = array(); while (true) { $flagBits = $reader->readShort(); $flags[] = $flagBits; if (($flagBits & 1) == 0) { break; } } $shift = 0; $data = array(); foreach ($this->propertyTypes as $key => $proptype) { if ($shift == 0) { if (!$flags) { break; } $flagBits = array_shift($flags); $shift = 15; } if ($flagBits & 1 << $shift) { $proptype = ucfirst($proptype); $data[$key] = $reader->{'read' . $proptype}(); } $shift -= 1; } $this->properties = $data; }
/** * Read an AMQP table, and return as a PHP array. keys are strings, * values are (type,value) tuples. * * @return array * @throws \Exception */ public function readTable() { $this->_bitcount = $this->_bits = 0; $tlen = $this->readPhpInt(); if ($tlen < 0) { throw new \Exception('Table is longer than supported'); } $tableData = new Reader($this->_rawread($tlen)); $result = array(); while ($tableData->tell() < $tlen) { $name = $tableData->readShortstr(); $ftype = $tableData->_rawread(1); if ($ftype == 'S') { $val = $tableData->readLongstr(); } else { if ($ftype == 'I') { $val = $tableData->_readSignedLong(); } else { if ($ftype == 'D') { $e = $tableData->readOctet(); $n = $tableData->_readSignedLong(); $val = new Decimal($n, $e); } else { if ($ftype == 'T') { $val = $tableData->readTimestamp(); } else { if ($ftype == 'F') { $val = $tableData->readTable(); // recursion } else { error_log(sprintf('Usupported table field type %s', $ftype)); $val = null; } } } } } $result[$name] = array($ftype, $val); } return $result; }
/** * @return \AMQP\Message * @throws \Exception */ public function waitContent() { $frm = $this->nextFrame(); $frameType = $frm[0]; $payload = $frm[1]; if ($frameType != 2) { throw new \Exception("Expecting Content header"); } $payloadReader = new Reader(substr($payload, 0, 12)); $classId = $payloadReader->readShort(); $weight = $payloadReader->readShort(); $bodySize = $payloadReader->readLonglong(); $msg = new Message(); $msg->load_properties(substr($payload, 12)); $bodyParts = array(); $bodyReceived = 0; while (bccomp($bodySize, $bodyReceived) == 1) { $frm = $this->nextFrame(); $frameType = $frm[0]; $payload = $frm[1]; /* * @todo add constants for the frameType identification */ if ($frameType != 3) { throw new \Exception(sprintf('Expecting Content body, received frame type %s', $frameType)); } $bodyParts[] = $payload; $bodyReceived = bcadd($bodyReceived, strlen($payload)); } $msg->body = implode('', $bodyParts); if ($this->autoDecode && isset($msg->content_encoding)) { try { $msg->body = $msg->decode(); } catch (\Exception $e) { if ($this->debug) { Helper::debugMsg(sprintf('Ignoring body decoding exception: %s', $e->getMessage())); } } } return $msg; }
/** * return a failed message * * @param \AMQP\Wire\Reader $args */ protected function basicReturn(\AMQP\Wire\Reader $args) { $reply_code = $args->readShort(); $reply_text = $args->readShortstr(); $exchange = $args->readShortstr(); $routing_key = $args->readShortstr(); $msg = $this->wait(); }
/** * propose connection tuning parameters * * @param \AMQP\Wire\Reader $args */ protected function tune(Reader $args) { $v = $args->readShort(); if ($v) { $this->channelMax = $v; } $v = $args->readLong(); if ($v) { $this->frameMax = $v; } $this->heartbeat = $args->readShort(); $this->xTuneOk($this->channelMax, $this->frameMax, 0); }