/** * {@inheritdoc} */ public function sendBinary(ReadableStream $stream, int $priority = 0) : Awaitable { return $this->writer->execute(function () use($stream) { $type = Frame::BINARY; $reserved = Frame::RESERVED1; $context = $this->deflate->getCompressionContext(); $len = 0; try { $chunk = (yield $stream->readBuffer(4092)); while (null !== ($next = (yield $stream->readBuffer(4092)))) { $chunk = \deflate_add($context, $chunk, \ZLIB_SYNC_FLUSH); $len += (yield $this->writeFrame(new Frame($type, $chunk, false, $reserved))); $chunk = $next; $type = Frame::CONTINUATION; $reserved = 0; } if ($chunk !== null) { $chunk = \substr(\deflate_add($context, $chunk, $this->deflate->getCompressionFlushMode()), 0, -4); $len += (yield $this->writeFrame(new Frame($type, $chunk, true, $reserved))); } return $len; } finally { $stream->close(); } }, $priority); }
/** * Read next chunk from temp file. * * Fall back to reading from buffered source stream if contents of the temp file have been read. */ protected function readNextChunk() : \Generator { $chunk = (yield $this->stream->readBuffer($this->bufferSize)); if ($chunk === null) { $chunk = (yield $this->source->readBuffer($this->bufferSize)); if ($chunk === null) { $this->body->computeSize(); $this->source->close(); } else { $this->body->incrementOffset((yield $this->stream->write($chunk))); } $chunk = (yield $this->stream->readBuffer($this->bufferSize)); } return $chunk; }
/** * {@inheritdoc} */ public function getReadableStream() : Awaitable { if ($this->temp) { $this->temp->rewind(); return new Success(new BufferedBodyStream($this->temp, $this->stream, $this->bufferSize, $this)); } if ($this->size !== null) { return new Success(new ReadableMemoryStream($this->buffer)); } return new Coroutine(function () { $buffer = (yield $this->stream->readBuffer($this->bufferSize)); $len = \strlen($buffer); if ($len < $this->bufferSize) { $this->buffer = $buffer; $this->size = $len; return new ReadableMemoryStream($buffer); } $this->temp = (yield LoopConfig::currentFilesystem()->tempStream()); $this->offset += (yield $this->temp->write($buffer)); return new BufferedBodyStream($this->temp, $this->stream, $this->bufferSize, $this); }); }
/** * Stream a binary WebSocket message. * * @param ReadableStream $stream * @param int $priority * @return int Number of transmitted bytes. * * @throws \InvalidArgumentException When the text is not UTF-8 encoded. */ public function sendBinary(ReadableStream $stream, int $priority = 0) : Awaitable { return $this->writer->execute(function () use($stream) { $type = Frame::BINARY; $len = 0; try { $chunk = (yield $stream->readBuffer(4092)); while (null !== ($next = (yield $stream->readBuffer(4092)))) { $len += (yield $this->writeFrame(new Frame($type, $chunk, false))); $chunk = $next; $type = Frame::CONTINUATION; } if ($chunk !== null) { $len += (yield $this->writeFrame(new Frame($type, $chunk))); } return $len; } finally { $stream->close(); } }, $priority); }