/** * 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; }