* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Predis\Protocol\Text; use Predis\CommunicationException; use Predis\ResponseError; use Predis\ResponseQueued; use Predis\Command\CommandInterface; use Predis\Connection\ComposableConnectionInterface; use Predis\Iterator\MultiBulkResponseSimple; use Predis\Protocol\ProtocolException; use Predis\Protocol\ProtocolProcessorInterface; /** * Protocol processor for the standard Redis wire protocol. * * @link http://redis.io/topics/protocol * @author Daniele Alessandri */ class ProtocolProcessor implements ProtocolProcessorInterface { protected $mbiterable; protected $serializer; /** * */ public function __construct() { $this->mbiterable = false; $this->serializer = new RequestSerializer(); } /** * {@inheritdoc} */ public function write(ComposableConnectionInterface $connection, CommandInterface $command) { $connection->writeBytes($this->serializer->serialize($command)); } /** * {@inheritdoc} */ public function read(ComposableConnectionInterface $connection) { $chunk = $connection->readLine(); $prefix = $chunk[0]; $payload = substr($chunk, 1); switch ($prefix) { case '+': // inline switch ($payload) { case 'OK': return true; case 'QUEUED': return new ResponseQueued(); default: return $payload; } case '$': // bulk $size = (int) $payload; if ($size === -1) { return null; } return substr($connection->readBytes($size + 2), 0, -2); case '*': // multi bulk $count = (int) $payload; if ($count === -1) { return null; } if ($this->mbiterable) { return new MultiBulkResponseSimple($connection, $count); } $multibulk = array(); for ($i = 0; $i < $count; $i++) { $multibulk[$i] = $this->read($connection); } return $multibulk; case ':': // integer return (int) $payload; case '-': // error return new ResponseError($payload); default: CommunicationException::handle(new ProtocolException( $connection, "Unknown prefix: '$prefix'" )); } } /** * Enables or disables returning multibulk responses as specialized PHP * iterators used to stream bulk elements of a multibulk response instead * returning a plain array. * * Please note that streamable multibulk replies are not globally supported * by the abstractions built-in into Predis such as for transactions or * pipelines. Use them with care! * * @param bool $value Enable or disable streamable multibulk responses. */ public function useIterableMultibulk($value) { $this->mbiterable = (bool) $value; } }