/**
* onRead
* @return void
*/
protected function onRead()
{
start:
if ($this->state === static::STATE_STANDBY) {
if (($hdr = $this->readExact(2)) === false) {
return;
// not enough data
}
$u = unpack('S', $hdr);
$this->responseCode = $u[1];
$this->state = static::STATE_PACKET_HDR;
}
if ($this->state === static::STATE_PACKET_HDR) {
if ($this->responseCode === static::REPL_KVAL) {
$this->result = [];
if (($hdr = $this->readExact(9)) === false) {
return;
// not enough data
}
$this->encoding = Binary::getByte($hdr);
$this->responseLength = Binary::getDword($hdr, true) - 4;
$this->totalNum = Binary::getDword($hdr, true);
$this->readedNum = 0;
$this->state = static::STATE_PACKET_DATA;
} else {
if (($hdr = $this->lookExact(5)) === false) {
return;
// not enough data
}
$this->encoding = Binary::getByte($hdr);
$pl = Binary::getDword($hdr, true);
if ($this->getInputLength() < 5 + $pl) {
return;
// not enough data
}
$this->drain(5);
$this->responseLength = $pl;
if ($this->responseLength > $this->pool->maxAllowedPacket) {
$this->log('max-allowed-packet (' . $this->pool->config->maxallowedpacket->getHumanValue() . ') exceed, aborting connection');
$this->finish();
return;
}
if ($this->responseCode === static::REPL_ERR_NOT_FOUND) {
$this->drain($this->responseLength);
$this->result = null;
$this->isFinal = true;
$this->totalNum = 0;
$this->readedNum = 0;
$this->executeCb();
} elseif ($this->responseCode === static::REPL_OK) {
$this->drain($this->responseLength);
$this->result = true;
$this->isFinal = true;
$this->totalNum = 0;
$this->readedNum = 0;
$this->executeCb();
} elseif ($this->responseCode === static::REPL_ERR_MEM || $this->responseCode === static::REPL_ERR_NAN || $this->responseCode === static::REPL_ERR_LOCKED) {
$this->drain($this->responseLength);
$this->result = false;
$this->isFinal = true;
$this->totalNum = 0;
$this->readedNum = 0;
$this->executeCb();
} else {
if ($this->responseCode === static::REPL_KVAL && $this->totalNum <= 0) {
$this->drain($this->responseLength);
$this->isFinal = true;
$this->totalNum = 0;
$this->readedNum = 0;
$this->result = [];
$this->executeCb();
} else {
$this->state = static::STATE_PACKET_DATA;
}
}
}
}
if ($this->state === static::STATE_PACKET_DATA) {
if ($this->responseCode === static::REPL_KVAL) {
$keyAdded = false;
nextElement:
$l = $this->getInputLength();
if ($l < 9) {
goto cursorCall;
}
if (($hdr = $this->lookExact($o = 4)) === false) {
goto cursorCall;
}
$keyLen = Binary::getDword($hdr, true);
if (($key = $this->lookExact($keyLen, $o)) === false) {
goto cursorCall;
}
$o += $keyLen;
if (($encoding = $this->lookExact(1, $o)) === false) {
goto cursorCall;
}
$encoding = ord($encoding);
++$o;
if (($hdr = $this->lookExact(4, $o)) === false) {
goto cursorCall;
}
$o += 4;
$valLen = Binary::getDword($hdr, true);
if ($o + $valLen > $l) {
goto cursorCall;
}
$this->drain($o);
if ($encoding === static::GB_ENC_NUMBER) {
$val = $this->read($valLen);
$this->result[$key] = $valLen === 8 ? Binary::getQword($val, true) : Binary::getDword($val, true);
} else {
$this->result[$key] = $this->read($valLen);
}
$keyAdded = true;
if (++$this->readedNum >= $this->totalNum) {
$this->isFinal = true;
$this->executeCb();
goto start;
} else {
goto nextElement;
}
cursorCall:
if ($keyAdded) {
$this->onResponse->executeAndKeepOne($this);
}
return;
} else {
if (($this->result = $this->readExact($this->responseLength)) === false) {
$this->setWatermark($this->responseLength);
return;
}
$this->setWatermark(2, $this->pool->maxAllowedPacket);
if ($this->encoding === static::GB_ENC_NUMBER) {
$this->result = $this->responseLength === 8 ? Binary::getQword($this->result, true) : Binary::getDword($this->result, true);
}
$this->isFinal = true;
$this->totalNum = 1;
$this->readedNum = 1;
$this->executeCb();
}
}
goto start;
}