readLine(); while (preg_match('/\{(?\d+)}\r\n$/', $raw, $matches)) { $raw .= $stream->read((int) $matches['bytes']); $raw .= $stream->readLine(); } $line = $this->parser->parse($raw); if ($line instanceof CommandContinuation) { $continuationHandler->continue(); continue; } $responseBuilder->addLine($line); } while (!$responseBuilder->hasStatus()); return $responseBuilder->build(); } /** * Streams parsed response lines one at a time as a Generator, yielding each * untagged Line immediately as it arrives from the socket. The terminal * Status line is NOT yielded; instead it is set as the generator return * value so callers can retrieve it via $gen->getReturn() after exhaustion. * * @throws CommandFailed if the tagged status is NO or BAD * * @return Generator */ public function stream(string $statusTag, ResponseStream $stream, ContinuationHandler $continuationHandler): Generator { $status = null; do { $raw = $stream->readLine(); while (preg_match('/\{(?\d+)}\r\n$/', $raw, $matches)) { $raw .= $stream->read((int) $matches['bytes']); $raw .= $stream->readLine(); } $line = $this->parser->parse($raw); if ($line instanceof CommandContinuation) { $continuationHandler->continue(); continue; } if ($line instanceof Status && $line->tag === $statusTag) { $status = $line; break; } yield $line; } while (true); if ($status->type !== StatusType::OK) { throw CommandFailed::withStatus($status); } return $status; } }